wake-up-neo.net

GROUP BY ohne Aggregatfunktion

Ich versuche, GROUP BY (neu in Oracle Dbms) ohne Aggregatfunktion zu verstehen.
Wie funktioniert es?
Ich habe es versucht. 

EMP-Tabelle, auf der ich meine SQL ausführen werde.
EMP TABLE

SELECT ename , sal
FROM emp
GROUP BY ename , sal

Result

SELECT ename , sal  
FROM emp  
GROUP BY ename;  

Ergebnis

ORA-00979: kein GROUP BY-Ausdruck
00979. 00000 - "kein GROUP BY-Ausdruck"
*Ursache:
*Aktion:
Fehler bei Zeile: 397 Spalte: 16 

SELECT ename , sal  
FROM emp  
GROUP BY sal;  

Ergebnis

ORA-00979: kein GROUP BY-Ausdruck
00979. 00000 - "kein GROUP BY-Ausdruck"
*Ursache:
* Aktion: Fehler bei Zeile: 411 Spalte: 8 

SELECT empno , ename , sal  
FROM emp  
GROUP BY sal , ename;  

Ergebnis

ORA-00979: kein GROUP BY-Ausdruck
00979. 00000 - "kein GROUP BY-Ausdruck"
*Ursache:
* Aktion: Fehler in Zeile: 425 Spalte: 8 

SELECT empno , ename , sal  
FROM emp  
GROUP BY empno , ename , sal;  

Result

Im Grunde muss die Anzahl der Spalten gleich der Anzahl der Spalten in der GROUP BY-Klausel sein, aber ich verstehe immer noch nicht, warum oder was los ist.

46
XForCE07

So funktioniert GROUP BY. Es dauert mehrere Reihen und verwandelt sie in eine Reihe. Aus diesem Grund muss es wissen, was mit allen kombinierten Zeilen zu tun ist, wenn für einige Spalten (Felder) unterschiedliche Werte vorhanden sind. Deshalb haben Sie für jedes Feld, das Sie auswählen möchten, zwei Optionen: Entweder fügen Sie es in die GROUP BY-Klausel ein oder verwenden Sie es in einer Aggregatfunktion, damit das System weiß, wie Sie das Feld kombinieren möchten.

Angenommen, Sie haben diese Tabelle:

Name | OrderNumber
------------------
John | 1
John | 2

Wenn Sie GROUP BY Name sagen, woher weiß es dann, welche Bestellnummer im Ergebnis angezeigt wird? Sie fügen also entweder orderNumber in group by ein, was zu diesen beiden Zeilen führt. Oder Sie zeigen anhand einer Aggregatfunktion, wie Sie mit den Bestellnummern umgehen. Beispielsweise MAX(OrderNumber), was bedeutet, dass das Ergebnis John | 2 oder SUM(OrderNumber) ist, was bedeutet, dass das Ergebnis John | 3 ist.

83
Tobberoth

Angesichts dieser Daten:

Col1  Col2  Col3
 A     X     1
 A     Y     2
 A     Y     3
 B     X     0
 B     Y     3
 B     Z     1

Diese Abfrage 

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3

Würde genau dieselbe Tabelle ergeben.

Diese Abfrage:

SELECT Col1, Col2 FROM data GROUP BY Col1, Col2

Würde ergeben 

Col1  Col2
 A     X  
 A     Y  
 B     X  
 B     Y  
 B     Z  

Nun eine Abfrage:

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2

Ein Problem würde entstehen: Die Zeile mit A, Y ist das Ergebnis der Gruppierung der beiden Zeilen 

 A     Y     2
 A     Y     3

Welcher Wert sollte also in Spalte 3, '2' oder '3' stehen?

Normalerweise würden Sie eine Gruppe verwenden, um z. eine Summe:

SELECT Col1, Col2, SUM(Col3) FROM data GROUP BY Col1, Col2

In der Reihe hatten wir also ein Problem mit jetzt bekommen wir (2 + 3) = 5.

Die Gruppierung nach allen Ihren Spalten in Ihrer Auswahl entspricht praktisch der Verwendung von DISTINCT. In diesem Fall ist es vorzuziehen, das DISTINCT-Schlüsselwort Word zu verwenden.

Also statt 

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3

benutzen

SELECT DINSTINCT Col1, Col2, Col3 FROM data
20
oerkelens

Sie haben eine strikte Anforderung der GROUP BY-Klausel. Für jede Spalte, die nicht in der group-by-Klausel enthalten ist, muss eine Funktion angewendet werden, um alle Datensätze für die übereinstimmende "Gruppe" auf einen einzelnen Datensatz (Summe, Maximum, Minute usw.) zu reduzieren.

Wenn Sie alle abgefragten (ausgewählten) Spalten in der GROUP BY-Klausel auflisten, fordern Sie im Wesentlichen, dass doppelte Datensätze aus der Ergebnismenge ausgeschlossen werden. Dies hat den gleichen Effekt wie SELECT DISTINCT, wodurch auch doppelte Zeilen aus der Ergebnismenge entfernt werden.

20
Mister_Tom

Der einzige Anwendungsfall für GROUP BY ohne Aggregation ist der Fall, wenn Sie GROUP BY mehr Spalten als ausgewählt auswählen. In diesem Fall werden die ausgewählten Spalten möglicherweise wiederholt. Ansonsten können Sie auch ein DISTINCT verwenden.

Es ist erwähnenswert, dass für andere RDBMS nicht alle nicht aggregierten Spalten in GROUP BY enthalten sein müssen. Wenn beispielsweise in PostgreSQL die Primärschlüsselspalten einer Tabelle in GROUP BY enthalten sind, müssen die anderen Spalten dieser Tabelle nicht sein, da sie für jede separate Primärschlüsselspalte garantiert eindeutig sind. Ich habe mir in der Vergangenheit gewünscht, dass Oracle dasselbe getan hätte, wie es in vielen Fällen für kompaktes SQL möglich wäre.

6
David Aldridge

Lassen Sie mich einige Beispiele geben.

Betrachten Sie diese Daten.

CREATE TABLE DATASET ( VAL1 CHAR ( 1 CHAR ),
                   VAL2 VARCHAR2 ( 10 CHAR ),
                   VAL3 NUMBER );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'b', 'b-details', 2 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'a', 'a-details', 1 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'c', 'c-details', 3 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'a', 'dup', 4 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'c', 'c-details', 5 );

COMMIT;

Was ist jetzt in der Tabelle

SELECT * FROM DATASET;

VAL1 VAL2             VAL3
---- ---------- ----------
b    b-details           2
a    a-details           1
c    c-details           3
a    dup                 4
c    c-details           5

5 rows selected.

- mit gruppieren nach

SELECT
      VAL1,
      COUNT ( * )
FROM
      DATASET A
GROUP BY
      VAL1;

VAL1   COUNT(*)
---- ----------
b             1
a             2
c             2

3 rows selected.

--Gruppe mit mehreren Spalten zusammenfassen, jedoch Teilspalte auswählen

SELECT
      VAL1,
      COUNT ( * )
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

VAL1  
---- 
b             
c             
a             
a             

4 rows selected.

--Keine Aggregatgruppe mit mehreren Spalten

SELECT
      VAL1,
      VAL2
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

    VAL1  
    ---- 
    b    b-details
    c    c-details
    a    dup
    a    a-details

    4 rows selected.

--Keine Aggregatgruppe mit mehreren Spalten

SELECT
      VAL1
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

    VAL1  
    ---- 
    b
    c
    a
    a

    4 rows selected.

Sie haben N Spalten in select (außer Aggregationen), dann sollten Sie N oder N + x Spalten haben

4
SriniV

Wenn Sie eine Spalte in der SELECT-Klausel haben, wie wird sie dann ausgewählt, wenn mehrere Zeilen vorhanden sind? ja, jede Spalte in der SELECT-Klausel sollte auch in der GROUP BY-Klausel sein, Sie können Aggregatfunktionen in SELECT verwenden ... 

sie können eine Spalte in der GROUP BY-Klausel haben, die sich nicht in der SELECT-Klausel befindet, ansonsten jedoch nicht

3
ogres

Unterabfrage verwenden, z. 

SELECT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3
FROM tbl1 GROUP BY field1,field2

OR

SELECT DISTINCT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3
FROM tbl1
2

Als Zusatz

grundsätzlich muss die Anzahl der Spalten der Anzahl der Spalten in der GROUP BY-Klausel entsprechen

ist keine korrekte Aussage.

  • Jedes Attribut, das nicht Teil der GROUP BY-Klausel ist, kann nicht zur Auswahl verwendet werden
  • Jedes Attribut, das Teil der GROUP BY-Klausel ist, kann für die Auswahl verwendet werden, ist jedoch nicht obligatorisch. 
1
sancz

Ich weiß, Sie sagten, Sie möchten die Gruppe verstehen, wenn Sie über folgende Daten verfügen:

COL-A  COL-B  COL-C  COL-D
  1      Ac      C1     D1
  2      Bd      C2     D2
  3      Ba      C1     D3
  4      Ab      C1     D4
  5      C       C2     D5

Und Sie möchten, dass die Daten folgendermaßen aussehen:

COL-A  COL-B  COL-C  COL-D
  4      Ab      C1     D4
  1      Ac      C1     D1
  3      Ba      C1     D3
  2      Bd      C2     D2
  5      C       C2     D5

Sie verwenden:

select * from table_name
order by col-c,colb

Weil ich denke, dass Sie das tun wollen.

0
user2839702