Aşağıdaki gibi bir tablo (PostgreSQL 9.4'te) var:
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');
Şimdi verilen tarihler ve her tür için, dates_ranges
her bir tarihten kaç satır düştüğünü hesaplamak istiyorum . Sıfırlar atlanabilir.
İstenen sonuç:
+-------+------------+----+
| 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 |
+-------+------------+----+
İki çözüm buldum, biri LEFT JOIN
veGROUP 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
ve biri ile LATERAL
, biraz daha hızlı:
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
Bu sorguyu yazmak için daha iyi bir yol olduğunu merak ediyorum? Ve nasıl 0 sayısı ile tarih-tür çiftleri dahil etmek?
Gerçekte birkaç farklı tür, beş yıla kadar süre (1800 tarih) ve dates_ranges
tabloda ~ 30 bin satır vardır (ancak önemli ölçüde büyüyebilir).
Hiçbir dizin yok. Benim durumumda kesin olmak gerekirse, bu alt sorgulamanın bir sonucudur, ancak soruyu bir konu ile sınırlandırmak istedim, bu yüzden daha genel.
2018-01-31
ya 2018-01-30
da 2018-01-29
içinde değil?
generate_series
harici parametrelerdir - dates_ranges
tablodaki tüm aralıkları kapsaması gerekmez . Sanırım ilk soruya gelince, anlamıyorum - satırlar dates_ranges
bağımsız, üst üste binmeyi belirlemek istemiyorum.
(1,2018-01-01,2018-01-15)
ve(1,2018-01-20,2018-01-25)
kaç tane çakışan tarihinizin olduğunu belirlerken bunu hesaba katmak ister misiniz?