Đây là một truy vấn nhanh để minh họa hành vi:
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)
Kết quả của truy vấn trên có thể được xem tại đây ( SQLFiddle tại đây ):
| 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 |
Ít người nghĩ đến các khung ngầm được áp dụng cho các hàm cửa sổ có ORDER BY
mệnh đề. Trong trường hợp này, các cửa sổ được đặt mặc định thành khung RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
. (RANGE không hoàn toàn giống ROWS, nhưng đó là một câu chuyện khác). Hãy nghĩ về nó theo cách này:
- Trên hàng có
v = 1
khung của cửa sổ được sắp xếp kéo dài theov IN (1)
- Trên hàng có
v = 2
khung của cửa sổ được sắp xếp kéo dài theov IN (1, 2)
- Trên hàng có
v = 3
khung của cửa sổ được sắp xếp kéo dài theov IN (1, 2, 3)
- Trên hàng có
v = 4
khung của cửa sổ đã đặt hàng kéo dài theov IN (1, 2, 3, 4)
Nếu bạn muốn ngăn chặn hành vi đó, bạn có hai lựa chọn:
- Sử dụng
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
mệnh đề cho đã đặt hàng chức năng cửa sổ - Không sử dụng
ORDER BY
mệnh đề trong các hàm cửa sổ cho phép bỏ qua chúng (dưới dạngMAX(v) OVER()
)
Các chi tiết khác được giải thích trong bài viết này về LEAD()
, LAG()
, FIRST_VALUE()
và LAST_VALUE()