Saya punya daftar pesanan
Column | Type | Modifiers
------------+-----------------------------+-----------------------------------------------------
id | integer | not null default nextval('orders_id_seq'::regclass)
client_id | integer | not null
start_date | date | not null
end_date | date |
order_type | character varying | not null
Data memiliki pesanan berdiri non tumpang tindih untuk client_id dan kadang-kadang pesanan sementara yang mengesampingkan urutan berdiri pada itu start_date ketika mereka memiliki client_id yang cocok. Ada batasan level aplikasi yang membuat pesanan dari jenis yang sama tidak tumpang tindih.
id | client_id | start_date | end_date | order_type
----+-----------+------------+------------+------------
17 | 11 | 2014-02-05 | | standing
18 | 15 | 2014-07-16 | 2015-07-19 | standing
19 | 16 | 2015-04-01 | | standing
20 | 16 | 2015-07-18 | 2015-07-18 | temporary
Sebagai contoh, pada 2015-07-18
klien 16 memiliki urutan # 20 sebagai pesanan aktif karena menimpa urutan berdiri # 19. Dengan beberapa keributan saya menemukan cara yang efisien untuk menanyakan id pesanan aktif pada tanggal.
SELECT id from (
SELECT
id,
first_value(id) OVER (PARTITION BY client_id ORDER BY order_type DESC) active_order_id
FROM orders
WHERE start_date <= ? and (end_date is null OR end_date >= ?)
) active_orders
WHERE id = active_order_id
Jika Anda menanyakan ini dengan 2015-07-18
sebagai placeholder, Anda akan mendapatkannya
id
----
17
18
20
Rencana kueri pada kueri ini dibandingkan dengan beberapa ide saya yang lain (seperti sub kueri yang menghitung jumlah pesanan sementara untuk seorang klien pada suatu tanggal) cukup kecil dan saya cukup senang dengannya. (Desain meja, saya tidak senang tentang)
Sekarang, saya perlu mencari semua pesanan aktif untuk rentang tanggal yang digabung dengan tanggal mereka aktif. Misalnya, dengan rentang tanggal 2015-07-18
hingga 2015-07-19
saya ingin hasil berikut.
active_date | id
------------+----
2015-07-18 | 17
2015-07-18 | 18
2015-07-18 | 20
2015-07-19 | 17
2015-07-19 | 18
2015-07-19 | 19
Pesan 20 ganti pesanan 19 2015-07-18
tetapi tidak aktif 2015-07-19
.
Saya menemukan dengan generate_series()
saya dapat menghasilkan berbagai tanggal, tetapi saya tidak tahu bagaimana cara menggabungkannya dengan ini untuk mendapatkan daftar tanggal dan memesan id. Firasat saya adalah gabungan silang tetapi saya tidak tahu bagaimana cara membuatnya bekerja dalam keadaan ini.
Terima kasih
UPDATE Menambahkan biola sql .
sumber
Jawaban:
Saya akan menggunakan
select distinct on
alih-alih fungsi jendela, lalu bergabung saja beberapa hari.http://sqlfiddle.com/#!15/5a420/16/0
Saya bisa menguraikan lebih banyak jika ada sesuatu yang tidak jelas.
sumber
distinct on
ini lebih dioptimalkan daripada permintaan jendela. By the way, saya harus menyebutkan bahwa ini adalah masalah "top-in-group" yang umum di SQL: stackoverflow.com/questions/3800551/…Tulis fungsi yang mengambil satu tanggal sebagai parameter dan mengembalikan daftar tanggal + id yang memiliki pesanan.
Kemudian, gunakan generate_series seperti yang Anda sarankan dan panggil fungsi tersebut pada rentang tanggal.
Ini adalah strategi umum ketika berhadapan dengan kondisi kompleks dalam SQL.
Saya sudah memasukkan beberapa kode di bawah ini, tetapi jawaban SQL di atas jauh lebih sederhana.
Inilah fungsinya:
Dan bagaimana menyebutnya:
SQLFiddle
sumber