W zapytaniach SQL używamy klauzuli Group by do zastosowania funkcji agregujących.
- Ale jaki jest cel używania wartości liczbowej zamiast nazwy kolumny z klauzulą Grupuj według? Na przykład: Grupuj według 1.
Komentarze
Odpowiedź
To jest naprawdę bardzo złe rzecz do zrobienia IMHO i nie jest obsługiwana w większości innych platform bazodanowych.
Powody, dla których ludzie to robią:
- „są leniwi – nie wiem, dlaczego ludzie myślą, że ich produktywność poprawia się, pisząc zwięzły kod, zamiast pisać przez dodatkowe 40 milisekund, aby uzyskać bardziej dosłowny kod.
Powody, dla których jest źle:
-
nie dokumentuje się samemu – ktoś będzie musiał przeanalizować listę SELECT w celu ustalenia grupowania. W rzeczywistości byłoby to trochę bardziej przejrzyste w SQL Server, który nie obsługuje kowboja, który- grupowanie wie-co-się-zdarzy, takie jak MySQL.
-
jest kruche – ktoś przychodzi i zmienia listę SELECT, ponieważ użytkownicy biznesowi chcieli innego wyniku raportu, a teraz wynik jest bałaganem. Gdybyś użył nazw kolumn w GROUP BY, kolejność na liście SELECT nie miałaby znaczenia.
SQL Server obsługuje ORDER BY [porządkowa]; oto kilka równoległych argumentów przeciwko jego użyciu:
Odpowiedź
MySQL umożliwia GROUP BY
z aliasami ( Problemy z aliasami kolumn ). Byłoby znacznie lepiej niż zrobienie GROUP BY
z liczbami.
- Niektórzy ludzie nadal tego uczą
- Niektóre mają
column number
na diagramach SQL . Jedna linia mówi: sortuje wynik według podanego numeru kolumny lub wyrażenia. Jeśli wyrażenie jest pojedynczym parametrem, wartość jest interpretowana jako numer kolumny. Ujemne numery kolumn odwracają porządek sortowania. - Apache przestał być używany, ponieważ SQL Server ma
Google ma wiele przykładów jego używania i dlaczego wielu przestało go używać.
Szczerze mówiąc, nie używałem numerów kolumn dla ORDER BY
i GROUP BY
od 1996 roku (pracowałem wtedy nad Oracle PL / SQL Development). Używanie numerów kolumn jest naprawdę dla starszych użytkowników, a kompatybilność wsteczna pozwala takim programistom używać MySQL i innych RDBMS, które nadal na to zezwalaj.
Odpowiedź
Rozważ poniższy przypadek:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Musisz poznać liczbę pobrań na usługę dziennie, biorąc pod uwagę aplikacje i aplikacje jako tę samą usługę. Grupowanie według date, services
spowodowałoby, że Apps
i Applications
byłyby traktowane jako oddzielne usługi.
W takim przypadku zapytanie wyglądałoby tak:
select date, services, sum(downloads) as downloads from test.zvijay_test group by date,services
A dane wyjściowe:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Ale nie tego chcesz, ponieważ grupowanie aplikacji i aplikacji jest wymagane. Więc co możemy zrobić?
Jednym ze sposobów jest zamiana Apps
na Applications
za pomocą CASE
wyrażenie lub funkcję IF
, a następnie grupowanie ich według usług jako:
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,services
Ale to nadal grupuje usługi uwzględniające Apps
i Applications
jako różne usługi i daje te same wyniki co poprzednio:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Grupowanie według numeru kolumny umożliwia grupowanie danych w kolumnie z aliasami.
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,2;
I w ten sposób daje pożądane wyjście, jak poniżej:
+------------+--------------+-----------+ | date | services | downloads | +------------+--------------+-----------+ | 2016-05-31 | Applications | 4 | | 2016-05-31 | Videos | 2 | | 2016-06-01 | Applications | 9 | | 2016-06-01 | Videos | 2 | +------------+--------------+-----------+
I „ve czytać wiele razy, że jest to leniwy sposób pisania zapytań lub grupowania w kolumnie z aliasami, nie działa w MySQL, ale jest to sposób grupowania kolumn z aliasami.
To nie jest preferowany sposób pisania zapytań, używaj go tylko wtedy, gdy naprawdę musisz zgrupować kolumny z aliasami.
Komentarze
- " Ale to nadal grupuje usługi, które traktują aplikacje i aplikacje jako różne usługi i daje te same wyniki, co poprzednio ".Czy nie ' t nie zostałoby rozwiązane, gdyby ' wybrał inną (niepowodującą konfliktu) nazwę dla aliasu?
- @ Daddy32 Dokładnie moja myśl. Lub nawet zagnieżdżaj jeszcze raz (grupuj po zaznaczeniu)
Odpowiedz
Nie ma ważnego powodu, aby z niego korzystać. Jest to po prostu leniwy skrót, specjalnie zaprojektowany, aby utrudnić niektórym z trudnych programistom ustalenie grupowania lub sortowania w późniejszym czasie lub aby kod nie działał źle, gdy ktoś zmienia kolejność kolumn. Miej wzgląd na innych programistów i nie rób tego.
Odpowiedź
To zadziałało dla mnie. Kod grupuje wiersze do 5 grup.
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
Wynik będzie następujący
Odpowiedź
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;
Rozważ powyższe zapytania: Grupuj według 1 oznacza grupowanie według pierwszej kolumny i grupowanie według 1,2 oznacza grupowanie według pierwszej i drugiej kolumny oraz grupowanie według 1, 2, 3 oznacza grupowanie według pierwszej drugiej i trzeciej kolumny. Na przykład:
ten obraz przedstawia dwie pierwsze kolumny pogrupowane według 1, 2, tj. nie bierze pod uwagę różnych wartości dep_date w celu znalezienia liczby (aby obliczyć liczbę, brane są pod uwagę wszystkie różne kombinacje pierwszych dwóch kolumn) podczas gdy drugie zapytanie skutkuje tym
. Tutaj bierze pod uwagę wszystkie pierwsze trzy kolumny i różne wartości, aby znaleźć liczbę, tj. Grupuje według wszystkich pierwszych trzech kolumn (w celu obliczenia zliczania brane są pod uwagę wszystkie różne kombinacje pierwszych trzech kolumn).
order by 1
tylko podczas siedzenia po moniciemysql>
. W kodzie użyjORDER BY id ASC
. Zwróć uwagę na wielkość liter, wyraźną nazwę pola i wyraźny kierunek kolejności.