Câu hỏi đã cũ, nhưng giải pháp này đơn giản và nhanh hơn những gì đã được đăng cho đến nay:
SELECT b.machine_id
, batch
, timestamp_sta
, timestamp_stp
, min(timestamp_sta) OVER w AS batch_start
, max(timestamp_stp) OVER w AS batch_end
FROM db_data.sta_stp a
JOIN db_data.ll_lu b ON a.ll_lu_id = b.id
WINDOW w AS (PARTITION BY batch, b.machine_id) -- No ORDER BY !
ORDER BY timestamp_sta, batch, machine_id; -- why this ORDER BY?
Nếu bạn thêm ORDER BY
vào định nghĩa khung cửa sổ, mỗi hàng tiếp theo có ORDER BY
lớn hơn biểu thức có một khung bắt đầu muộn hơn. Không min()
cũng không phải first_value()
có thể trả về dấu thời gian "đầu tiên" cho toàn bộ phân vùng sau đó. Không có ORDER BY
tất cả các hàng của cùng một phân vùng đều là hàng ngang hàng và bạn nhận được kết quả mong muốn.
ORDER BY
đã thêm của bạn hoạt động (không phải là định nghĩa trong khung cửa sổ, định nghĩa bên ngoài), nhưng dường như không có ý nghĩa và làm cho truy vấn đắt hơn. Bạn có thể nên sử dụng ORDER BY
điều khoản đồng ý với định nghĩa khung cửa sổ của bạn để tránh chi phí sắp xếp bổ sung:
...
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;
Tôi không thấy cần phải có DISTINCT
trong truy vấn này. Bạn chỉ có thể thêm nó nếu bạn thực sự cần nó. Hoặc DISTINCT ON ()
. Nhưng sau đó ORDER BY
mệnh đề thậm chí còn phù hợp hơn. Xem:
Nếu bạn cần một số (các) cột khác từ cùng một hàng (trong khi vẫn sắp xếp theo dấu thời gian), ý tưởng của bạn với FIRST_VALUE()
và LAST_VALUE()
có thể là con đường để đi. Bạn có thể cần phải thêm điều này vào định nghĩa khung cửa sổ sau đó :
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Xem: