Câu trả lời cho câu hỏi cập nhật
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (PARTITION BY status ORDER BY id) last_val
,lag(status) OVER (PARTITION BY val ORDER BY id) last_status
FROM t1
) x
WHERE status = 1
AND (last_val <> val OR last_status = 0)
Làm thế nào?
Giống như lần trước, nhưng lần này kết hợp hai chức năng cửa sổ. Chuyển đổi trên một thiết bị đủ điều kiện nếu ..
1. thiết bị cuối cùng được bật là một khác một.
2. hoặc cùng một thiết bị đã bị tắt trong mục cuối cùng của nó. Trường hợp góc với NULL
đối với hàng đầu tiên của phân vùng là không liên quan, vì khi đó hàng đã đủ điều kiện trong 1.
Câu trả lời cho phiên bản gốc của câu hỏi.
Nếu tôi hiểu chính xác nhiệm vụ của bạn, truy vấn đơn giản này sẽ thực hiện công việc:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Trả về hàng 1, 3, 6, 7 theo yêu cầu.
Làm thế nào?
Truy vấn con bỏ qua tất cả việc tắt, vì đó chỉ là tiếng ồn, theo mô tả của bạn. Thoát các mục nhập nơi thiết bị được bật. Trong số đó, chỉ những mục nhập đó bị loại, khi đã bật cùng một thiết bị (mục nhập cuối cùng đang bật). Sử dụng chức năng cửa sổ lag()
cho điều đó. Đặc biệt, tôi cung cấp 0
như mặc định để che trường hợp đặc biệt của hàng đầu tiên - giả sử rằng không có thiết bị nào có val = 0
.
Nếu có, hãy chọn một số không thể khác.
Nếu không có số nào là không thể, hãy để trường hợp đặc biệt là NULL
với lag(val) OVER ...
và trong truy vấn bên ngoài, hãy kiểm tra với:
WHERE last_on IS DISTINCT FROM val