sql >> Databáze >  >> RDS >> Sqlserver

SQL:Last_Value() vrací špatný výsledek (ale First_Value() funguje dobře)

Zde je rychlý dotaz pro ilustraci tohoto chování:

select 
  v,

  -- FIRST_VALUE() and LAST_VALUE()
  first_value(v) over(order by v) f1,
  first_value(v) over(order by v rows between unbounded preceding and current row) f2,
  first_value(v) over(order by v rows between unbounded preceding and unbounded following) f3,
  last_value (v) over(order by v) l1,
  last_value (v) over(order by v rows between unbounded preceding and current row) l2,
  last_value (v) over(order by v rows between unbounded preceding and unbounded following) l3,

  -- For completeness' sake, let's also compare the above with MAX()
  max        (v) over() m1,
  max        (v) over(order by v) m2,
  max        (v) over(order by v rows between unbounded preceding and current row) m3,
  max        (v) over(order by v rows between unbounded preceding and unbounded following) m4
from (values(1),(2),(3),(4)) t(v)

Výstup výše uvedeného dotazu si můžete prohlédnout zde (SQLFiddle zde ):

| V | F1 | F2 | F3 | L1 | L2 | L3 | M1 | M2 | M3 | M4 |
|---|----|----|----|----|----|----|----|----|----|----|
| 1 |  1 |  1 |  1 |  1 |  1 |  4 |  4 |  1 |  1 |  4 |
| 2 |  1 |  1 |  1 |  2 |  2 |  4 |  4 |  2 |  2 |  4 |
| 3 |  1 |  1 |  1 |  3 |  3 |  4 |  4 |  3 |  3 |  4 |
| 4 |  1 |  1 |  1 |  4 |  4 |  4 |  4 |  4 |  4 |  4 |

Málokdo si myslí o implicitních rámcích, které se aplikují na funkce okna, které přebírají ORDER BY doložka. V tomto případě jsou okna ve výchozím nastavení rámce RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW . (RANGE není úplně stejný jako ROWS, ale to je jiný příběh). Přemýšlejte o tom takto:

  • Na řádku s v = 1 rám objednaného okna se rozprostírá v IN (1)
  • Na řádku s v = 2 rám objednaného okna se rozprostírá v IN (1, 2)
  • Na řádku s v = 3 rám objednaného okna se rozprostírá v IN (1, 2, 3)
  • Na řádku s v = 4 rám objednaného okna se rozprostírá v IN (1, 2, 3, 4)

Pokud chcete tomuto chování zabránit, máte dvě možnosti:

  • Použít explicitní ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING doložka pro objednáno funkce okna
  • Nepoužívejte ORDER BY klauzule v těch funkcích okna, které umožňují jejich vynechání (jako MAX(v) OVER() )

Další podrobnosti jsou vysvětleny v tento článek o LEAD() , LAG() , FIRST_VALUE() a LAST_VALUE()



  1. codeigniter aktivní záznam vnořený dotaz

  2. ImportError:Žádný modul s názvem mysql.connector nepoužívá Python3?

  3. Proč různé výsledky počítání při po sobě jdoucích čteních?

  4. Problém se čtením data Delphi SQL