Warum verwenden wir Group by 1 und Group by 1,2,3 in SQL-Abfragen?

26

In SQL-Abfragen verwenden wir die Group by-Klausel, um Aggregatfunktionen anzuwenden.

  • Aber wozu dient die Verwendung eines numerischen Werts anstelle eines Spaltennamens mit der Group by-Klausel? Zum Beispiel: Gruppiere nach 1.
ursitesion
quelle
3
Verwenden Sie order by 1nur , wenn in der Sitzung mysql> prompt. Verwenden Sie im Code ORDER BY id ASC. Beachten Sie den Fall, den expliziten Feldnamen und die explizite Reihenfolge.
Dotancohen

Antworten:

28

Dies ist eine wirklich schlechte Sache, um IMHO zu tun, und es wird in den meisten anderen Datenbankplattformen nicht unterstützt.

Die Gründe, warum Menschen es tun:

  • Sie sind faul - ich weiß nicht, warum die Leute glauben, dass sich ihre Produktivität verbessert, wenn sie knappen Code schreiben, anstatt zusätzliche 40 Millisekunden zu tippen, um viel mehr wörtlichen Code zu erhalten.

Die Gründe, warum es schlecht ist:

  • Es ist keine Selbstdokumentation - jemand muss die SELECT-Liste analysieren, um die Gruppierung herauszufinden. In SQL Server, das Cowboy-Who-know-what-will-happen-Gruppierungen wie MySQL nicht unterstützt, wäre dies tatsächlich etwas klarer.

  • es ist spröde - jemand kommt herein und ändert die SELECT-Liste, weil die Geschäftsbenutzer eine andere Berichtsausgabe wollten, und jetzt ist Ihre Ausgabe ein Durcheinander. Wenn Sie in GROUP BY Spaltennamen verwendet hätten, wäre die Reihenfolge in der SELECT-Liste irrelevant.

SQL Server unterstützt ORDER BY [ordinal]; Hier sind einige parallele Argumente gegen seine Verwendung:

Aaron Bertrand
quelle
9

Mit MySQL können Sie GROUP BYAliase bearbeiten ( Probleme mit Spalten- Aliasen ). Das wäre weitaus besser als GROUP BYmit Zahlen.

Google hat viele Beispiele für die Verwendung und warum viele es nicht mehr verwenden.

Um ehrlich zu sein, habe ich für ORDER BYund GROUP BYseit 1996 keine Spaltennummern verwendet (ich habe zu der Zeit Oracle PL / SQL-Entwicklung durchgeführt). Die Verwendung von Spaltennummern ist wirklich für Oldtimer gedacht, und die Abwärtskompatibilität ermöglicht es solchen Entwicklern, MySQL und andere RDBMSs zu verwenden, die dies noch zulassen.

RolandoMySQLDBA
quelle
8

Betrachten Sie den folgenden 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 |
+------------+--------------+-----------+

Sie müssen die Anzahl der Downloads pro Dienst und Tag ermitteln, wenn Sie Apps und Anwendungen als denselben Dienst betrachten. Eine Gruppierung nach date, serviceswürde zu separaten Diensten führen Appsund Applicationsals solche betrachtet werden.

In diesem Fall wäre die Abfrage:

 select date, services, sum(downloads) as downloads
 from test.zvijay_test
 group by date,services

Und Ausgabe:

+------------+--------------+-----------+
| 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 |
+------------+--------------+-----------+

Dies ist jedoch nicht das, was Sie möchten, da die Gruppierung von Anwendungen und Apps die Voraussetzung ist. Also was können wir tun?

Eine Möglichkeit besteht darin, Appsdurch die ApplicationsVerwendung eines CASEAusdrucks oder der IFFunktion zu ersetzen und diese dann über Dienste zu gruppieren als:

select 
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test 
group by date,services

Aber diese noch Gruppen Dienstleistungen unter Berücksichtigung Appsund Applicationsals unterschiedliche Dienste und gibt die gleiche Leistung wie vorher:

+------------+--------------+-----------+
| 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 |
+------------+--------------+-----------+

Durch Gruppieren über eine Spaltennummer können Sie Daten in einer mit Alias ​​versehenen Spalte gruppieren.

select
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test
group by date,2;

Und so erhalten Sie die gewünschte Ausgabe wie folgt:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         4 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         9 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Ich habe oft gelesen, dass dies eine träge Methode zum Schreiben von Abfragen oder zum Gruppieren über eine mit Alias ​​versehene Spalte ist, die in MySQL nicht funktioniert. Dies ist jedoch die Methode zum Gruppieren über mit Alias ​​versehene Spalten.

Dies ist nicht die bevorzugte Methode zum Schreiben von Abfragen. Verwenden Sie diese Methode nur, wenn Sie eine Gruppierung über eine Alias-Spalte durchführen müssen.

imVJ
quelle
" Damit werden Dienste, die Apps und Anwendungen als unterschiedliche Dienste betrachten, immer noch gruppiert und es wird die gleiche Ausgabe wie zuvor erzielt." Wäre dies nicht gelöst, wenn Sie einen anderen (nicht in Konflikt stehenden) Namen für den Alias ​​gewählt hätten?
Daddy32
3

Es gibt keinen gültigen Grund, es zu verwenden. Es ist einfach eine faule Abkürzung, die speziell dafür entwickelt wurde, es einigen hartnäckigen Entwicklern zu erschweren, Ihre Gruppierung oder Sortierung zu einem späteren Zeitpunkt herauszufinden oder zuzulassen, dass der Code kläglich versagt, wenn jemand die Spaltenreihenfolge ändert. Seien Sie rücksichtsvoll gegenüber Ihren Mitentwicklern und tun Sie es nicht.

BriteSponge
quelle
0

Das ist für mich gearbeitet. Der Code gruppiert die Zeilen in bis zu 5 Gruppen.

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

Das Ergebnis ist wie folgt

Bildbeschreibung hier eingeben

Schiff shuk - www.shipshuk.com
quelle
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;

Betrachten Sie die obigen Fragen: Gruppieren nach 1 bedeutet Gruppieren nach der ersten Spalte und Gruppieren nach 1,2 bedeutet Gruppieren nach der ersten und zweiten Spalte und Gruppieren nach 1,2,3 bedeutet Gruppieren nach der ersten zweiten und dritten Spalte. Zum Beispiel:

Gruppe von 1,2

Dieses Bild zeigt die ersten beiden Spalten, gruppiert nach 1,2, dh es werden nicht die unterschiedlichen Werte von dep_date berücksichtigt, um den Zählerstand zu ermitteln (um den Zählerstand zu berechnen, werden alle unterschiedlichen Kombinationen der ersten beiden Spalten berücksichtigt), wohingegen die zweite Abfrage dies bewirkt Gruppe von 1,2,3

Bild. Hierbei werden alle ersten drei Spalten berücksichtigt und es werden unterschiedliche Werte zum Ermitteln der Anzahl verwendet, dh es wird eine Gruppierung nach allen ersten drei Spalten durchgeführt (um die Anzahl zu berechnen, werden alle unterschiedlichen Kombinationen der ersten drei Spalten berücksichtigt).

Kodierer
quelle