Pertanyaannya sudah lama, tetapi solusi ini lebih sederhana dan lebih cepat daripada yang telah diposting sejauh ini:
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?
Jika Anda menambahkan ORDER BY
untuk definisi bingkai jendela, setiap baris berikutnya dengan ORDER BY
greater yang lebih besar ekspresi memiliki awal bingkai kemudian. Baik min()
atau first_value()
dapat mengembalikan stempel waktu "pertama" untuk seluruh partisi. Tanpa ORDER BY
semua baris dari partisi yang sama adalah peer dan Anda mendapatkan hasil yang diinginkan.
ORDER BY
yang Anda tambahkan berfungsi (bukan yang ada dalam definisi bingkai jendela, yang terluar), tetapi tampaknya tidak masuk akal dan membuat kueri lebih mahal. Anda mungkin harus menggunakan ORDER BY
klausa yang sesuai dengan definisi bingkai jendela Anda untuk menghindari biaya sortir tambahan:
...
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;
Saya tidak melihat perlunya DISTINCT
dalam kueri ini. Anda bisa menambahkannya jika Anda benar-benar membutuhkannya. Atau DISTINCT ON ()
. Tapi kemudian ORDER BY
klausa menjadi lebih relevan. Lihat:
Jika Anda memerlukan beberapa kolom lain dari baris yang sama (sambil masih mengurutkan berdasarkan cap waktu), ide Anda dengan FIRST_VALUE()
dan LAST_VALUE()
mungkin cara untuk pergi. Anda mungkin perlu menambahkan ini ke definisi bingkai jendela lalu :
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Lihat: