sql >> Databáze >  >> RDS >> Oracle

Funkce Oracle Lag s dynamickým parametrem

Předpokládám další sloupec col0 který obsahuje zřejmá kritéria řazení vašich dat, jako je váš col1 ukázková data nejsou ve skutečnosti seřazena správně (opakované koncové hodnoty A a E ).

Líbí se mi MODEL doložka pro tyto účely. Následující dotaz přináší očekávaný výsledek:

WITH t(col0, col1, col2, col3, col4) AS (
  SELECT 1, 'A', 0, 1, 5 FROM DUAL UNION ALL
  SELECT 2, 'B', 0, 4, 0 FROM DUAL UNION ALL
  SELECT 3, 'C', 2, 0, 0 FROM DUAL UNION ALL
  SELECT 4, 'D', 0, 0, 0 FROM DUAL UNION ALL
  SELECT 5, 'E', 3, 5, 0 FROM DUAL UNION ALL
  SELECT 6, 'F', 0, 3, 0 FROM DUAL UNION ALL
  SELECT 7, 'G', 0, 3, 1 FROM DUAL UNION ALL
  SELECT 8, 'A', 0, 1, 5 FROM DUAL UNION ALL
  SELECT 9, 'E', 3, 5, 0 FROM DUAL
)
SELECT * FROM t
MODEL
  DIMENSION BY (row_number() OVER (ORDER BY col0) rn)
  MEASURES (col1, col2, col3, col4)
  RULES (
    col2[any] = DECODE(col2[cv(rn)], 0, NVL(col2[cv(rn) - 1], 0), col2[cv(rn)]),
    col3[any] = DECODE(col3[cv(rn)], 0, NVL(col3[cv(rn) - 1], 0), col3[cv(rn)]),
    col4[any] = DECODE(col4[cv(rn)], 0, NVL(col4[cv(rn) - 1], 0), col4[cv(rn)])
  )

Výsledek:

RN   COL1  COL2  COL3  COL4
1    A     0     1     5
2    B     0     4     5
3    C     2     4     5
4    D     2     4     5
5    E     3     5     5
6    F     3     3     5
7    G     3     3     1
8    A     3     1     5
9    E     3     5     5

SQLFiddle

Poznámka ke klauzuli MODEL vs. přístupy založené na funkci okna

Zatímco výše uvedené vypadá cool (nebo děsivě, v závislosti na vašem úhlu pohledu), měli byste určitě preferovat použití přístupu založeného na funkci okna, jak ukazují další elegantní odpovědi od nop77svk (pomocí LAST_VALUE() IGNORE NULLS ) nebo MT0 (pomocí LAG() IGNORE NULLS ) . Tyto odpovědi jsem podrobněji vysvětlil v tomto příspěvku na blogu .



  1. XA vs. výkon ovladače JDBC bez XA?

  2. Jak nainstalovat SQLite a SQLite Browser v Ubuntu

  3. jak formátovat datum pocházející z MYSQL

  4. Jak InnoDB ukládá sloupce znaků?