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

26

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

  • Но какова цель использования числового значения вместо имени столбца с предложением Group by? Например: сгруппировать по 1.
ursitesion
источник
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 и другие РСУБД, которые все еще допускают это.

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

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

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

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

BriteSponge
источник
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

Результат будет следующим

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

Корабль Шук - www.shipshuk.com
источник
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

образ. Здесь рассматриваются все первые три столбца и существуют разные значения, чтобы найти счетчик, т. Е. Он группируется по всем первым трем столбцам (для расчета количества учитываются все различные комбинации первых трех столбцов).

кодировщик
источник