- Sử dụng
COALESCE
như @Justin cung cấp. -
Với
first_value()
/last_value()
bạn cần để thêmORDER BY
mệnh đề cho định nghĩa cửa sổ hoặc thứ tự là không xác định . Bạn vừa gặp may trong ví dụ này, vì các hàng xảy ra theo thứ tự ngay sau khi tạo bảng giả.
Sau khi bạn thêmORDER BY
, khung cửa sổ mặc định kết thúc ở hàng hiện tại và bạn cần viết hoa chữ thườnglast_value()
gọi - hoặc hoàn nguyên thứ tự sắp xếp trong khung cửa sổ như được minh họa trong ví dụ đầu tiên của tôi. -
Khi sử dụng lại định nghĩa cửa sổ nhiều lần,
WINDOW
rõ ràng mệnh đề đơn giản hóa cú pháp rất nhiều:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,first_value(part) OVER (PARTITION BY ring ORDER BY part DESC))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part);
Tốt hơn nữa , sử dụng lại định nghĩa cửa sổ tương tự, vì vậy Postgres có thể tính toán tất cả các giá trị trong một lần quét. Để điều này hoạt động, chúng tôi cần xác định khung cửa sổ tùy chỉnh :
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER w)
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring
ORDER BY part
RANGE BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING)
ORDER BY 1,2;
Bạn thậm chí có thể điều chỉnh định nghĩa khung cho từng lệnh gọi hàm cửa sổ:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER (w RANGE BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part)
ORDER BY 1,2;
Có thể nhanh hơn đối với các vòng có nhiều bộ phận. Bạn sẽ phải kiểm tra.
SQL Fiddle thể hiện cả ba bằng một trường hợp thử nghiệm cải tiến. Xem xét các kế hoạch truy vấn.
Tìm hiểu thêm về định nghĩa khung cửa sổ:
- Trong sách hướng dẫn.
- Hàm cửa sổ PostgreSQL:phân vùng theo so sánh
- Truy vấn PostgreSQL với ngày tối đa và ngày tối thiểu cộng với id được liên kết trên mỗi hàng