Tôi có một bảng (trong PostgreQuery 9.4) trông như thế này:
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');
Bây giờ tôi muốn tính toán cho các ngày đã cho và cho mọi loại, vào bao nhiêu hàng từ dates_ranges
mỗi ngày rơi. Zeros có thể được bỏ qua.
Kết quả như ý:
+-------+------------+----+
| 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 |
+-------+------------+----+
Tôi đã đưa ra hai giải pháp, một với LEFT JOIN
vàGROUP 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
và một với LATERAL
, nhanh hơn một chút:
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
Tôi tự hỏi có cách nào tốt hơn để viết truy vấn này không? Và làm thế nào để bao gồm các cặp ngày loại với số đếm 0?
Trong thực tế, có một vài loại khác nhau, thời gian lên tới năm năm (1800 ngày) và ~ 30k hàng trong dates_ranges
bảng (nhưng nó có thể tăng trưởng đáng kể).
Không có chỉ số. Nói chính xác trong trường hợp của tôi, đó là kết quả của việc truy vấn phụ, nhưng tôi muốn giới hạn câu hỏi trong một vấn đề, vì vậy nó mang tính tổng quát hơn.
2018-01-31
hay 2018-01-30
hoặc 2018-01-29
trong khi phạm vi đầu tiên có tất cả trong số họ?
generate_series
là các tham số bên ngoài - chúng không nhất thiết bao gồm tất cả các phạm vi trong dates_ranges
bảng. Đối với câu hỏi đầu tiên tôi cho rằng tôi không hiểu nó - các hàng trong dates_ranges
độc lập, tôi không muốn xác định chồng chéo.
(1,2018-01-01,2018-01-15)
và(1,2018-01-20,2018-01-25)
bạn có muốn tính đến điều đó khi xác định có bao nhiêu ngày chồng chéo bạn có không?