Почему мы используем Группу по 1 и Группу по 1,2,3 в запросе SQL?


26

В SQL-запросах мы используем предложение Group by для применения агрегатных функций.

  • Но какова цель использования числового значения вместо имени столбца с предложением Group by? Например: сгруппировать по 1.

3
Используйте order by 1только сидя на mysql> подсказке. В коде используйте ORDER BY id ASC. Обратите внимание на регистр, явное имя поля и явное направление упорядочения.
Dotancohen

Ответы:


28

Это на самом деле очень плохо для IMHO, и это не поддерживается большинством других платформ баз данных.

Причины, по которым люди делают это:

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

Причины это плохо:

  • это не самодокументирование - кто-то должен будет разобрать список SELECT, чтобы выяснить группировку. На самом деле это было бы немного яснее в SQL Server, который не поддерживает группировку ковбой, который знает, что произойдет, как в MySQL.

  • это хрупко - кто-то входит и изменяет список SELECT, потому что бизнес-пользователи хотели другой вывод отчета, и теперь ваш вывод - беспорядок. Если бы вы использовали имена столбцов в GROUP BY, порядок в списке SELECT не имеет значения.

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


9

MySQL позволяет вам делать GROUP BYс псевдонимами ( проблемы с псевдонимами столбцов ). Это было бы намного лучше, чем GROUP BYс цифрами.

У Google есть много примеров его использования и почему многие перестали его использовать.

Если честно, я не использовал номера столбцов для ORDER BYи GROUP BYс 1996 года (в то время я занимался разработкой Oracle PL / SQL). Использование номеров столбцов действительно для старых таймеров, и обратная совместимость позволяет таким разработчикам использовать MySQL и другие РСУБД, которые все еще допускают это.


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, но это способ группировки по столбцам с псевдонимами.

Это не предпочтительный способ написания запросов, используйте его только тогда, когда вам действительно нужно сгруппировать по столбцу с псевдонимом.


« Но это все равно группирует сервисы, рассматривая Приложения и Приложения как разные сервисы и дает тот же результат, что и ранее ». Разве это не будет решено, если вы выбрали другое (не конфликтующее) имя для псевдонима?
Daddy32

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.