Oracle
 sql >> Datenbank >  >> RDS >> Oracle

PARTITION BY mit und ohne KEEP in Oracle

MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno)

Die Anweisung kann (ungefähr) von rechts nach links betrachtet werden:

  • OVER (PARTITION BY deptno) bedeutet, die Zeilen in verschiedene Gruppen von deptno zu unterteilen; dann
  • ORDER BY sal bedeutet, für jede Partition die Zeilen nach sal zu ordnen (implizit mit ASC Endauftrag); dann
  • KEEP (DENSE_RANK FIRST bedeutet, den geordneten Zeilen für jede Partition eine (aufeinanderfolgende) Rangfolge zu geben (Zeilen mit identischen Werten für die geordneten Spalten erhalten die gleiche Rangfolge) und alle Zeilen zu verwerfen, die nicht an erster Stelle stehen; und schließlich
  • MIN(sal) Geben Sie für die verbleibenden Zeilen jeder Partition das Mindestgehalt zurück.

In diesem Fall der MIN und DENSE_RANK FIRST arbeiten beide auf dem sal Spalte so wird dasselbe tun und KEEP (DENSE_RANK FIRST ORDER BY sal) ist überflüssig.

Wenn Sie jedoch eine andere Spalte für das Minimum verwenden, können Sie die Auswirkungen sehen:

SQL-Fiddle

Oracle 11g R2-Schema-Setup :

CREATE TABLE test (name, sal, deptno) AS
SELECT 'a', 1, 1 FROM DUAL
UNION ALL SELECT 'b', 1, 1 FROM DUAL
UNION ALL SELECT 'c', 1, 1 FROM DUAL
UNION ALL SELECT 'd', 2, 1 FROM DUAL
UNION ALL SELECT 'e', 3, 1 FROM DUAL
UNION ALL SELECT 'f', 3, 1 FROM DUAL
UNION ALL SELECT 'g', 4, 2 FROM DUAL
UNION ALL SELECT 'h', 4, 2 FROM DUAL
UNION ALL SELECT 'i', 5, 2 FROM DUAL
UNION ALL SELECT 'j', 5, 2 FROM DUAL;

Abfrage 1 :

SELECT DISTINCT
  MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS min_sal_first_sal,
  MAX(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS max_sal_first_sal,
  MIN(name) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS min_name_first_sal,
  MAX(name) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS max_name_first_sal,
  MIN(name) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) AS min_name_last_sal,
  MAX(name) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) AS max_name_last_sal,
  deptno
FROM test

Ergebnisse :

| MIN_SAL_FIRST_SAL | MAX_SAL_FIRST_SAL | MIN_NAME_FIRST_SAL | MAX_NAME_FIRST_SAL | MIN_NAME_LAST_SAL | MAX_NAME_LAST_SAL | DEPTNO |
|-------------------|-------------------|--------------------|--------------------|-------------------|-------------------|--------|
|                 1 |                 1 |                  a |                  c |                 e |                 f |      1 |
|                 4 |                 4 |                  g |                  h |                 i |                 j |      2 |