In SQL-querys gebruiken we Group by-clausule om geaggregeerde functies toe te passen.
- Maar wat is het doel achter het gebruik van numerieke waarde in plaats van kolomnaam met Group by-clausule? Bijvoorbeeld: groepeer op 1.
Reacties
Antwoord
Dit is eigenlijk een heel slechte iets te doen IMHO, en het wordt niet ondersteund in de meeste andere databaseplatforms.
De redenen waarom mensen het doen:
- ze “zijn lui – Ik weet niet waarom mensen denken dat hun productiviteit wordt verbeterd door beknopte code te schrijven in plaats van 40 milliseconden extra te typen om veel meer letterlijke code te krijgen.
De redenen waarom het slecht is:
-
het is niet zelfdocumenterend – iemand zal de SELECT-lijst moeten ontleden om de groepering te achterhalen. Het zou eigenlijk een beetje duidelijker zijn in SQL Server, dat cowboy niet ondersteunt die- weet-wat-zal-gebeuren groeperen zoals MySQL doet.
-
het is broos – iemand komt binnen en verandert de SELECT-lijst omdat de zakelijke gebruikers wilden een andere rapportuitvoer, en nu is uw uitvoer een puinhoop. Als u kolomnamen had gebruikt in de GROUP BY, zou de volgorde in de SELECT-lijst niet relevant zijn.
SQL Server ondersteunt ORDER BY [ordinal]; hier zijn enkele parallelle argumenten tegen het gebruik ervan:
Answer
Met MySQL kun je GROUP BY
doen met aliassen ( Problemen met kolomaliassen ). Dit zou veel beter zijn dan GROUP BY
doen met getallen.
- Sommige mensen leren het nog steeds
- Sommige hebben
column number
in SQL-diagrammen . Een regel zegt: Sorteert het resultaat op het opgegeven kolomnummer of op een uitdrukking. Als de uitdrukking een enkele parameter is, wordt de waarde geïnterpreteerd als een kolomnummer. Negatieve kolomnummers keren de sorteervolgorde om. - Apache heeft het gebruik ervan beëindigd omdat SQL Server dit heeft
Google heeft veel voorbeelden van het gebruik ervan en waarom velen het niet meer gebruiken.
Om eerlijk te zijn, ik heb “geen kolomnummers gebruikt voor ORDER BY
en GROUP BY
sinds 1996 (ik deed destijds Oracle PL / SQL Development). Het gebruik van kolomnummers is echt voor oldtimers en achterwaartse compatibiliteit stelt dergelijke ontwikkelaars in staat MySQL en andere RDBMSen te gebruiken die nog steeds toestaan.
Antwoord
Beschouw het volgende geval:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
U moet het aantal downloads per service per dag zien als Apps en Applicaties als dezelfde service worden beschouwd. Groeperen op date, services
zou ertoe leiden dat Apps
en Applications
als afzonderlijke services worden beschouwd.
In dat geval zou de vraag zijn:
select date, services, sum(downloads) as downloads from test.zvijay_test group by date,services
En uitvoer:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Maar dit is niet wat je wilt, aangezien het nodig is om applicaties en apps te groeperen. Dus wat kunnen we doen?
Een manier is om Apps
te vervangen door Applications
met een CASE
expressie of de IF
functie en ze vervolgens over services te groeperen als:
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,services
Maar dit groepeert nog steeds services waarbij Apps
en Applications
als verschillende services worden beschouwd en geeft dezelfde output als voorheen:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Door over een kolomnummer te groeperen, kunt u gegevens groeperen op een gealiaste kolom.
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,2;
En daardoor krijg je de gewenste output zoals hieronder:
+------------+--------------+-----------+ | 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 vaak lezen dat dit een luie manier is om queries te schrijven of groeperen over een alias-kolom werkt niet in MySQL, maar dit is de manier van groeperen over gealiasteerde kolommen.
Dit is niet de geprefereerde manier om queries te schrijven, gebruik het alleen wanneer je moet echt over een gealiaste kolom groeperen.
Reacties
- ” Maar dit groepeert nog steeds services die Apps en Applicaties beschouwen als verschillende services en geeft dezelfde output als voorheen “.Zou dit niet ‘ zijn opgelost als u ‘ een andere (niet-conflicterende) naam voor de alias hebt gekozen?
- @ Daddy32 Precies mijn gedachte. Of zelfs nog een keer nestelen (groep na selectie)
Antwoord
Er is geen geldige reden om het te gebruiken. Het is gewoon een luie snelkoppeling die speciaal is ontworpen om het moeilijk te maken voor een of andere ontwikkelaar die het moeilijk heeft om je groepering of sortering later te achterhalen, of om de code jammerlijk te laten mislukken wanneer iemand de kolomvolgorde verandert. Houd rekening met je mede-ontwikkelaars en doe het niet.
Antwoord
Dit werkt voor mij. De code groepeert de rijen met maximaal 5 groepen.
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
Het resultaat is als volgt
Antwoord
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;
Overweeg bovenstaande zoekopdrachten: groepeer op 1 om te groeperen op de eerste kolom en groepeer op 1,2 om te groeperen op de eerste en tweede kolom en groepeer op 1,2,3 middelen om te groeperen door eerste tweede en derde kolom. Voor bijvoorbeeld:
deze afbeelding toont de eerste twee kolommen gegroepeerd op 1,2, dwz er wordt geen rekening gehouden met de verschillende waarden van dep_date om de telling te vinden (om de telling te berekenen, wordt rekening gehouden met alle verschillende combinaties van de eerste twee kolommen) terwijl de tweede zoekopdracht dit
afbeelding. Hier wordt rekening gehouden met alle eerste drie kolommen en hun verschillende waarden om de telling te vinden, dwz het is gegroepeerd op basis van alle eerste drie kolommen (om de telling te berekenen, wordt rekening gehouden met alle afzonderlijke combinaties van de eerste drie kolommen).
order by 1
alleen als je zit bij demysql>
prompt. Gebruik in codeORDER BY id ASC
. Let op het hoofdlettergebruik, de expliciete veldnaam en de expliciete ordeningsrichting.