I SQL-frågor använder vi Group by clause för att tillämpa aggregerade funktioner.
- Men vad är syftet med att använda numeriskt värde istället för kolumnnamn med Group by clause? Till exempel: Gruppera efter 1.
Kommentarer
Svar
Detta är faktiskt riktigt dåligt sak att göra IMHO, och det stöds inte i de flesta andra databasplattformar.
Anledningarna till att människor gör det:
- de är ”lata – Jag vet inte varför människor tror att deras produktivitet förbättras genom att skriva kortkod snarare än att skriva in ytterligare 40 millisekunder för att få mycket mer bokstavlig kod.
Anledningarna till att det är ”dåligt:
-
det är inte självdokumenterande – någon kommer att behöva analysera SELECT-listan för att räkna ut grupperingen. Det skulle faktiskt vara lite tydligare i SQL Server, vilket inte stöder cowboy som- vet-vad-kommer-hända gruppering som MySQL gör.
-
det är sprött – någon kommer in och ändrar SELECT-listan på grund av affärsanvändarna ville ha en annan rapportutdata, och nu är din utdata en röra. Om du hade använt kolumnnamn i GROUP BY, skulle ordningen i SELECT-listan vara irrelevant.
SQL Server stöder ORDER BY [ordinal]; här är några parallella argument mot dess användning:
Svar
MySQL låter dig göra GROUP BY
med alias ( Problem med kolumnalias ). Detta skulle vara mycket bättre än att göra GROUP BY
med siffror.
- Vissa människor lär det fortfarande
- Vissa har
column number
i SQL-diagram . En rad säger: Sorterar resultatet efter det angivna kolumnnumret eller efter ett uttryck. Om uttrycket är en enda parameter tolkas värdet som ett kolumnnummer. Negativa kolumnnummer vänder sorteringsordningen. - Apache har avskaffat användningen eftersom SQL Server har
Google har många exempel på att använda det och varför många har slutat använda det.
För att vara ärlig mot dig har jag inte använt kolumnnummer för ORDER BY
och GROUP BY
sedan 1996 (jag gjorde Oracle PL / SQL-utveckling vid den tiden). Att använda kolumnnummer är verkligen för gammaldags och bakåtkompatibilitet gör att sådana utvecklare kan använda MySQL och andra RDBMS som tillåt fortfarande.
Svar
Tänk på följande fall:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Du måste ta reda på antalet nedladdningar per tjänst per dag och betraktar appar och applikationer som samma tjänst. Gruppering efter date, services
skulle resultera i att Apps
och Applications
betraktas som separata tjänster.
I så fall skulle frågan vara:
select date, services, sum(downloads) as downloads from test.zvijay_test group by date,services
Och Output:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Men detta är inte vad du vill eftersom applikationer och appar ska grupperas är kravet. Så vad kan vi göra?
Ett sätt är att ersätta Apps
med Applications
med en CASE
-uttryck eller IF
-funktionen och sedan gruppera dem över tjänster som:
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,services
Men detta grupperar fortfarande tjänster som betraktar Apps
och Applications
som olika tjänster och ger samma resultat som tidigare:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Genom att gruppera över ett kolumnnummer kan du gruppera data i en aliasad kolumn.
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,2;
Och därmed ger du önskad effekt enligt nedan:
+------------+--------------+-----------+ | date | services | downloads | +------------+--------------+-----------+ | 2016-05-31 | Applications | 4 | | 2016-05-31 | Videos | 2 | | 2016-06-01 | Applications | 9 | | 2016-06-01 | Videos | 2 | +------------+--------------+-----------+
Jag har läs många gånger att detta är ett lat sätt att skriva frågor eller gruppera över en aliasad kolumn fungerar inte i MySQL, men detta är sättet att gruppera över aliaserade kolumner.
Detta är inte det föredragna sättet att skriva frågor, använd det bara när du måste verkligen gruppera en aliaserad kolumn.
Kommentarer
- " Men detta grupperar fortfarande tjänster som betraktar appar och applikationer som olika tjänster och ger samma utdata som tidigare ".Skulle ' inte detta lösas om du ' har valt ett annat (icke-motstridigt) namn för aliaset?
- @ Daddy32 Exakt min tanke. Eller till och med häcka igen (grupp efter att ha valt)
Svar
Det finns ingen giltig anledning att använda det. Det är helt enkelt en lat genväg speciellt utformad för att göra det svårt för någon hårt pressad utvecklare att räkna ut din gruppering eller sortering senare eller låta koden misslyckas när någon ändrar kolumnordningen. Var hänsynsfull mot dina medutvecklare och gör det inte.
Svar
Detta fungerar för mig. Koden grupperar rader upp till 5 grupper.
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
Resultatet blir som följer
Svar
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;
Tänk på ovanstående frågor: Gruppera med 1 medel för att gruppera efter den första kolumnen och gruppera med 1,2 betyder att gruppera efter den första och andra kolumnen och gruppera med 1,2,3 betyder att gruppera av första andra och tredje kolumnen. Till exempel:
den här bilden visar de två första kolumnerna grupperade med 1,2, dvs det beaktas inte de olika värdena för dep_date för att hitta räkningen (för att beräkna räkna tas alla olika kombinationer av de två första kolumnerna i beaktande) medan den andra frågan resulterar i detta
bild. Här överväger alla de tre första kolumnerna och det finns olika värden för att hitta räkningen, det vill säga, det grupperas efter alla de tre första kolumnerna (för att beräkna räknar man alla olika kombinationer av de tre första kolumnerna).
order by 1
bara när du sitter vidmysql>
-prompten. I koden använder duORDER BY id ASC
. Lägg märke till fallet, det explicita fältnamnet och den explicita beställningsriktningen.