sql >> Database >  >> RDS >> Oracle

Oracle MIN als analytische functie - vreemd gedrag met ORDER BY?

Als u een ORDER BY . toevoegt naar de MIN analytische functie, verander je het in een "min tot nu toe" -functie in plaats van een algemeen minimum. Voor de laatste rij voor wat je ook partitioneert, de resultaten zullen hetzelfde zijn. Maar de voorgaande rijen kunnen een andere "min tot nu toe" hebben dan het algemene minimum.

De EMP gebruiken tabel als voorbeeld ziet u dat het minimumsalaris tot nu toe voor de afdeling uiteindelijk convergeert naar het algemene minimum voor de afdeling. En u kunt zien dat de "min tot nu toe"-waarde voor een bepaalde afdeling afneemt naarmate er lagere waarden worden aangetroffen.

SQL> ed
Wrote file afiedt.buf

  1  select ename,
  2         deptno,
  3         sal,
  4         min(sal) over (partition by deptno order by ename) min_so_far,
  5         min(sal) over (partition by deptno) min_overall
  6    from emp
  7*  order by deptno, ename
SQL> /

ENAME          DEPTNO        SAL MIN_SO_FAR MIN_OVERALL
---------- ---------- ---------- ---------- -----------
CLARK              10       2450       2450        1300
KING               10       5000       2450        1300
MILLER             10       1300       1300        1300
ADAMS              20       1110       1110         800
FORD               20       3000       1110         800
JONES              20       2975       1110         800
SCOTT              20       3000       1110         800
smith              20        800        800         800
ALLEN              30       1600       1600         950
BLAKE              30       2850       1600         950
MARTIN             30       1250       1250         950
SM0                30        950        950         950
TURNER             30       1500        950         950
WARD               30       1250        950         950
BAR
PAV

16 rows selected.

Het zou natuurlijk logischer zijn om deze vorm van de analytische functie te gebruiken wanneer u iets probeert te doen zoals het berekenen van een persoonlijk record dat u in toekomstige perioden als vergelijking kunt gebruiken. Als u de afnemende golfscores, kilometertijden of het gewicht van een persoon bijhoudt, kan het weergeven van persoonlijke records een vorm van motivatie zijn.

SQL> ed
Wrote file afiedt.buf

  1  with golf_scores as
  2  (  select 1 golfer_id, 80 score, sysdate dt from dual union all
  3     select 1, 82, sysdate+1 dt from dual union all
  4     select 1, 72, sysdate+2 dt from dual union all
  5     select 1, 75, sysdate+3 dt from dual union all
  6     select 1, 71, sysdate+4 dt from dual union all
  7     select 2, 74, sysdate from dual )
  8  select golfer_id,
  9         score,
 10         dt,
 11         (case when score=personal_best
 12               then 'New personal best'
 13               else null
 14           end) msg
 15    from (
 16  select golfer_id,
 17         score,
 18         dt,
 19         min(score) over (partition by golfer_id
 20                              order by dt) personal_best
 21    from golf_scores
 22*        )
SQL> /

 GOLFER_ID      SCORE DT        MSG
---------- ---------- --------- -----------------
         1         80 12-SEP-11 New personal best
         1         82 13-SEP-11
         1         72 14-SEP-11 New personal best
         1         75 15-SEP-11
         1         71 16-SEP-11 New personal best
         2         74 12-SEP-11 New personal best

6 rows selected.



  1. mysqli_connect():(HY000/2002):Kan geen verbinding maken met de lokale MySQL-server via socket

  2. Poolse tekens opslaan mysql

  3. PHP geeft afbeeldingen uit database weer

  4. wat is de juiste manier om te converteren tussen mysql datetime en python timestamp?