Saya punya tabel (dalam PostgreSQL 9.4) yang terlihat seperti ini:
CREATE TABLE dates_ranges (kind int, start_date date, end_date date);
INSERT INTO dates_ranges VALUES
(1, '2018-01-01', '2018-01-31'),
(1, '2018-01-01', '2018-01-05'),
(1, '2018-01-03', '2018-01-06'),
(2, '2018-01-01', '2018-01-01'),
(2, '2018-01-01', '2018-01-02'),
(3, '2018-01-02', '2018-01-08'),
(3, '2018-01-05', '2018-01-10');
Sekarang saya ingin menghitung untuk tanggal yang diberikan dan untuk setiap jenis, ke berapa banyak baris dari dates_ranges
setiap tanggal jatuh. Nol bisa dihilangkan.
Hasil yang diinginkan:
+-------+------------+----+
| kind | as_of_date | n |
+-------+------------+----+
| 1 | 2018-01-01 | 2 |
| 1 | 2018-01-02 | 2 |
| 1 | 2018-01-03 | 3 |
| 2 | 2018-01-01 | 2 |
| 2 | 2018-01-02 | 1 |
| 3 | 2018-01-02 | 1 |
| 3 | 2018-01-03 | 1 |
+-------+------------+----+
Saya telah datang dengan dua solusi, satu dengan LEFT JOIN
danGROUP BY
SELECT
kind, as_of_date, COUNT(*) n
FROM
(SELECT d::date AS as_of_date FROM generate_series('2018-01-01'::timestamp, '2018-01-03'::timestamp, '1 day') d) dates
LEFT JOIN
dates_ranges ON dates.as_of_date BETWEEN start_date AND end_date
GROUP BY 1,2 ORDER BY 1,2
dan satu dengan LATERAL
, yang sedikit lebih cepat:
SELECT
kind, as_of_date, n
FROM
(SELECT d::date AS as_of_date FROM generate_series('2018-01-01'::timestamp, '2018-01-03'::timestamp, '1 day') d) dates,
LATERAL
(SELECT kind, COUNT(*) AS n FROM dates_ranges WHERE dates.as_of_date BETWEEN start_date AND end_date GROUP BY kind) ss
ORDER BY kind, as_of_date
Saya bertanya-tanya apakah ini cara yang lebih baik untuk menulis pertanyaan ini? Dan bagaimana cara memasukkan pasangan jenis tanggal dengan 0 hitungan?
Pada kenyataannya ada beberapa jenis yang berbeda, periode hingga lima tahun (1800 tanggal), dan ~ 30rb baris dalam dates_ranges
tabel (tetapi bisa tumbuh secara signifikan).
Tidak ada indeks. Lebih tepatnya dalam kasus saya ini adalah hasil dari subquery, tapi saya ingin membatasi pertanyaan menjadi satu masalah, jadi lebih umum.
2018-01-31
atau 2018-01-30
atau 2018-01-29
di dalamnya ketika kisaran pertama memiliki semua dari mereka?
generate_series
adalah parameter eksternal - mereka tidak harus mencakup semua rentang dalam dates_ranges
tabel. Adapun pertanyaan pertama saya kira saya tidak memahaminya - baris dates_ranges
independen, saya tidak ingin menentukan tumpang tindih.
(1,2018-01-01,2018-01-15)
dan(1,2018-01-20,2018-01-25)
apakah Anda ingin memperhitungkannya ketika menentukan berapa banyak tanggal yang tumpang tindih yang Anda miliki?