Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

SQL:Last_Value() zwraca błędny wynik (ale First_Value() działa dobrze)

Oto krótkie zapytanie ilustrujące zachowanie:

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)

Wynik powyższego zapytania można zobaczyć tutaj (SQLFiddle tutaj ):

| 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 |

Niewiele osób myśli o niejawnych ramkach, które są stosowane do funkcji okna, które przyjmują ORDER BY klauzula. W tym przypadku okna domyślnie przyjmują ramkę RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW . (RANGE to nie to samo co ROWS, ale to już inna historia). Pomyśl o tym w ten sposób:

  • W wierszu z v = 1 uporządkowana ramka okna obejmuje v IN (1)
  • W wierszu z v = 2 uporządkowana ramka okna obejmuje v IN (1, 2)
  • W wierszu z v = 3 uporządkowana ramka okna obejmuje v IN (1, 2, 3)
  • W wierszu z v = 4 uporządkowana ramka okna obejmuje v IN (1, 2, 3, 4)

Jeśli chcesz zapobiec takiemu zachowaniu, masz dwie możliwości:

  • Użyj wyraźnych ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING klauzula zamówionego funkcje okien
  • Nie używaj ORDER BY klauzula w tych funkcjach okna, które pozwalają na ich pominięcie (jako MAX(v) OVER() )

Więcej szczegółów wyjaśniono w ten artykuł o LEAD() , LAG() , FIRST_VALUE() i LAST_VALUE()



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cross Join „n” razy przy stole

  2. instrukcja sql use ze zmienną

  3. Poznawanie obciążenia SQL Server

  4. Co to jest rozszerzona procedura składowana w MS SQL Server?

  5. Hiperłącz wartość w wyniku zapytania SQL Server w SSMS