SQL Server không biết hoặc không quan tâm đến thứ tự các hàng được chèn vào bảng. Nếu bạn cần đặt hàng cụ thể, hãy luôn sử dụng ORDER BY
. Trong ví dụ của bạn ORDER BY
không rõ ràng, trừ khi bạn bao gồm PK
vào ORDER BY
. Ngoài ra, LAST_VALUE
hàm có thể trả về kết quả lẻ nếu bạn không cẩn thận - xem bên dưới.
Bạn có thể nhận được kết quả mong đợi của mình bằng cách sử dụng MAX
hoặc LAST_VALUE
( SQLFiddle
). Chúng tương đương trong trường hợp này:
SELECT
PK, Id1, Id2
,MAX(PK) OVER (PARTITION BY Id1, Id2) AS MaxValue
,LAST_VALUE(PK) OVER (PARTITION BY Id1, Id2 ORDER BY PK rows between unbounded preceding and unbounded following) AS LastValue
FROM
Data
ORDER BY id1, id2, PK
Kết quả của truy vấn này sẽ giống nhau bất kể thứ tự các hàng được chèn ban đầu vào bảng. Bạn có thể thử đặt INSERT
các câu lệnh theo thứ tự khác nhau trong fiddle. Nó không ảnh hưởng đến kết quả.
Ngoài ra, LAST_VALUE
hoạt động không hoàn toàn như bạn mong đợi trực quan với cửa sổ mặc định (khi bạn chỉ có ĐẶT HÀNG THEO
trong HẾT
mệnh đề). Cửa sổ mặc định là ROWS GIỮA ROW CHÍNH XÁC VÀ HIỆN TẠI KHÔNG ĐƯỢC TỔ CHỨC
, trong khi bạn mong đợi nó sẽ là ROWS GIỮA BƯỚC CHÍNH XÁC ĐƯỢC CHƯA BAO GỒM VÀ CHƯA BAO LÂU SAU
. Đây là câu trả lời SO với giải thích tốt
. Liên kết đến câu trả lời SO này nằm trên trang MSDN cho LAST_VALUE
. Vì vậy, khi cửa sổ hàng được chỉ định rõ ràng trong truy vấn, nó sẽ trả về những gì cần thiết.
Nếu bạn muốn biết thứ tự các hàng được chèn vào bảng, tôi nghĩ, cách đơn giản nhất là sử dụng IDENTITY
. Vì vậy, định nghĩa về bảng của bạn sẽ thay đổi thành sau:
CREATE TABLE Data
(PK INT IDENTITY(1,1) PRIMARY KEY,
Id1 INT,
Id2 INT)
Khi bạn INSERT
vào bảng này, bạn không cần chỉ định giá trị cho PK
, máy chủ sẽ tự động tạo ra nó. Nó đảm bảo rằng các giá trị được tạo là duy nhất và đang tăng lên (với tham số tăng dương), ngay cả khi bạn có nhiều khách hàng chèn vào bảng cùng một lúc. Có thể có khoảng cách giữa các giá trị được tạo, nhưng thứ tự tương đối của các giá trị được tạo sẽ cho bạn biết hàng nào được chèn sau hàng nào.