Чому ми використовуємо групу по 1 та групу по 1,2,3 у запиті SQL?


26

У SQL-запитах ми використовуємо групування за допомогою пункту для застосування сукупних функцій.

  • Але яка мета використання числового значення замість імені стовпця з групою за пунктом? Наприклад: Згрупуйте по 1.

3
Використовуйте order by 1лише тоді, коли сидите за mysql> підказкою. У коді використовуйте ORDER BY id ASC. Зверніть увагу на регістр, явну назву поля та чітке впорядкування.
dotancohen

Відповіді:


28

Це насправді дуже погано робити IMHO, і це не підтримується в більшості інших платформ баз даних.

Причини, що люди роблять це:

  • вони ледачі - я не знаю, чому люди думають, що їх продуктивність підвищується, написавши короткий код, а не набираючи додаткові 40 мілісекунд, щоб отримати набагато більш буквальний код.

Причини це погано:

  • це не самодокументування - комусь доведеться проаналізувати список SELECT, щоб визначити групування. Насправді це було б трохи зрозуміліше в SQL Server, який не підтримує ковбоя, хто знає, що буде, що станеться, як це робить MySQL.

  • це крихко - хтось заходить і змінює список SELECT, оскільки ділові користувачі хотіли іншого виходу звіту, а тепер ваш вихід - безлад. Якщо ви використовували назви стовпців у групі BY, порядок у списку SELECT був би не має значення.

SQL Server підтримує ORDER BY [ordinal]; ось кілька паралельних аргументів проти його використання:


9

MySQL дозволяє робити GROUP BYпсевдоніми ( Проблеми з псевдонімом стовпців ). Це було б набагато краще, ніж робити GROUP BYз цифрами.

У Google є багато прикладів його використання і чому багато хто припинив її використовувати.

Щоб бути чесним з вами, я не використовував номери стовпців для ORDER BYі GROUP BYз 1996 року (я робив Oracle PL / SQL розвитку в той час). Використання номерів стовпців дійсно для старожилів, а зворотна сумісність дозволяє таким розробникам використовувати MySQL та інші RDBMS, які все ще дозволяють це робити.


8

Розглянемо нижче випадок:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-06-01 | Apps         |         3 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Videos       |         2 |
| 2016-06-01 | Apps         |         2 |
+------------+--------------+-----------+

Ви повинні дізнатися кількість завантажень за послугу в день, вважаючи додатки та програми одними і тими ж послугами. Групування за date, servicesрезультатами спричинить Appsі Applicationsвважатиметься окремими послугами.

У такому випадку запит буде:

 select date, services, sum(downloads) as downloads
 from test.zvijay_test
 group by date,services

І вихід:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Apps         |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Apps         |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Але це не те, що ви хочете, оскільки програми та додатки для групування - це вимога. То що ми можемо зробити?

Один із способів - це замінити Appsза Applicationsдопомогою CASEвиразу або IFфункції, а потім згрупувати їх по службах як:

select 
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test 
group by date,services

Але це все ще групує послуги, які розглядають Appsі Applicationsяк різні послуги, і дає такий же вихід, як і раніше:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Applications |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Групування за номером стовпця дозволяє групувати дані за псевдонімом стовпцем.

select
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test
group by date,2;

Таким чином, ви отримаєте бажаний результат, як показано нижче:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         4 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         9 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Я багато разів читав, що це ледачий спосіб написання запитів або групування за псевдонімним стовпцем не працює в MySQL, але це спосіб групування за псевдонімом стовпців.

Це не вподобаний спосіб написання запитів, використовуйте його лише тоді, коли вам дійсно потрібно згрупувати над псевдонімом стовпчик.


" Але це все ще групує послуги, які розглядають додатки та додатки як різні сервіси та дає такий же вихід, як і раніше ". Чи це не вирішиться, якщо ви вибрали інше (безконфліктне) ім’я для псевдоніма?
Тато32

3

Немає поважних причин використовувати його. Це просто ледачий ярлик, розроблений спеціально для того, щоб утруднити розробник важко розібратися у вашому групуванні чи сортування пізніше або дозволити коду невдало виходити з ладу, коли хтось змінить порядок стовпців. Будьте уважні до своїх колег-розробників і не робіть цього.


0

Це для мене працює. Код групує рядки до 5 груп.

SELECT
USR.UID,
USR.PROFILENAME,
(
    CASE 
    WHEN MOD(@curRow, 5) = 0 AND @curRow > 0 THEN
        @curRow := 0
    ELSE
        @curRow := @curRow + 1 
        /*@curRow := 1*/ /*AND @curCode := USR.UID*/
    END
) AS sort_by_total  
FROM
    SS_USR_USERS USR,
    (
        SELECT
            @curRow := 0,
            @curCode := ''
    ) rt
ORDER BY
    USR.PROFILENAME,
    USR.UID

Результат буде наступним

введіть тут опис зображення


0
SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2;

SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2,3;

Розглянемо вище запити: Група по 1 означає групувати за першим стовпцем і група по 1,2 означає групувати за першим і другим стовпцем, а група на 1,2,3 означає групувати за першим другим і третім стовпцем. Наприклад:

група на 1,2

на цьому зображенні показані перші два стовпці, згруповані по 1,2, тобто він не враховує різні значення dep_date для пошуку підрахунку (для обчислення підрахунку враховуються всі різні комбінації перших двох стовпців), тоді як другий запит призводить до цього групують на 1,2,3

зображення. Тут розглядаються всі перші три стовпці і є різні значення, щоб знайти підрахунок, тобто групується по всіх перших трьох стовпцях (для обчислення підрахунку всіх чітких комбінацій перших трьох стовпців враховується).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.