Tiêu chí ROWS và RANGE
Thuộc phần Kiến thức cơ bản trong hành trình SQL của Coddy. Bài học 69 trên 72.
Hiện tại, chúng ta chưa thể linh hoạt khi chọn số hàng ở trước hoặc sau để tính đến. Giờ đây, bạn có thể làm điều đó với tiêu chí ROWS và RANGE. Để sử dụng chúng, ta viết:
OVER (ROWS BETWEEN --START-- AND --END--)
OVER (RANGE BETWEEN --START-- AND --END--)
Và ta có thể chỉ định các tùy chọn sau:
CURRENT ROW: hàng hiện tạin PRECEDING: các hàng trước hàng hiện tạin FOLLOWING: các hàng sau hàng hiện tại
Điểm khác biệt giữa ROWS & RANGE là tiêu chí ROWS không xét đến các giá trị, mà chỉ xét vị trí, còn RANGE xác định cửa sổ theo khoảng giá trị thay vì vị trí hàng.
Với RANGE, ta phải chỉ định ORDER BY --column_name--, vì nếu không, nó sẽ không biết cách chọn cửa sổ.
Ví dụ:
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWINGỞ đây, câu lệnh tạo một cửa sổ gồm hàng hiện tại, hàng trước đó và hàng sau đó.
ORDER BY levels
RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWINGỞ đây, câu lệnh tạo một cửa sổ gồm cấp độ hiện tại, một cấp độ trước đó và một cấp độ sau đó cho mỗi cấp độ (được sắp xếp theo thứ tự tăng dần). Nếu cấp độ hiện tại là 5 thì cửa sổ sẽ gồm các cấp độ 4, 5 và 6.
Lưu ý: Việc dùng RANGE BETWEEN có thể khiến cửa sổ của bạn bao gồm nhiều hàng hơn, vì nó bao gồm tất cả các hàng có cùng giá trị với những hàng trong phạm vi, trong khi ROWS BETWEEN luôn bao gồm cùng một số hàng (nếu có đủ hàng trong tập dữ liệu).
Ngoài ra, với ngày tháng được lưu dưới dạng văn bản (chẳng hạn '2024-01-05'), độ lệch RANGE không thực hiện phép tính ngày tháng: với 1 PRECEDING, cửa sổ chỉ chứa các hàng có cùng ngày. Để đếm số ngày, hãy sắp xếp theo một con số, chẳng hạn julianday(date).
Đây là một ví dụ đơn giản để minh họa sự khác nhau giữa ROWS và RANGE:
Khi dùng ROWS:
SELECT employee_name, salary,
AVG(salary) OVER (
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
) as avg_salary_rowsCách dùng RANGE:
SELECT employee_name, salary,
AVG(salary) OVER (
ORDER BY salary
RANGE BETWEEN 1000 PRECEDING AND 1000 FOLLOWING
) as avg_salary_rangeThử thách
DễCác bảng và cột hiện có:
newspapers:date,num_newspapers
Trong thử thách này, chúng ta có dữ liệu về báo được sản xuất. Bạn hãy tìm số báo trung bình được in trong hai ngày trước hàng hiện tại và một ngày sau đó. Ngoài ra, hãy tìm hiệu giữa số báo được in nhiều nhất và ít nhất từ ngày hiện tại đến ba ngày trước đó. Đặt tên cho hai cột này lần lượt là avg_newspapers và diff_newspapers.
Tự làm thử
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Kiến thức cơ bản
2Điều kiện
Kiến thức cơ bản về điều kiệnTừ khóa ANDTừ khóa ORTừ khóa NOTKết hợp nhiều điều kiệnDấu ngoặc đơnGiá trị logic3Định dạng giá trị trả về cụ thể
Giá trị nullSắp xếp kết quả phần 1Sắp xếp kết quả phần 2Ôn tập: Công ty an ninh mạngGiới hạn số bản ghiÔn tập: Nhà máy sản xuất xe6Thử thách nhập môn
Ôn tập: bầu cử quốc hộiÔn tập: cảnh sát bắt giữ tội phạmÔn tập: vật chứa đồ uống tại quầy barÔn tập: kỹ sư tạo cột mới9Nhiều bảng
Phép nối cơ bản phần 1Phép nối cơ bản phần 2Ôn tập về phép nốiPhép tự nốiÔn tập về phép tự nốiHợpĐơn giản hóa truy vấn bằng từ khóa WITHÔn tập về truy vấn WITHÔn tập về nhà thầu bất động sản12Hàm cửa sổ phần 2
Hàm RANK và DENSE_RANKÔn tập: RANK và DENSE_RANKHàm NTILEHàm tổng hợpTiêu chí ROWS và RANGETự luyện tập: Playground SQL