Xem xét ý tưởng đằng sau truy vấn:
select distinct on (domain, new_date) *
from (
select new_date::date
from generate_series('2016-04-12', '2016-04-17', '1d'::interval) new_date
) s
left join a_table t on date <= new_date
order by domain, new_date, date desc;
new_date | domain | date | visitors | hits
------------+-----------------+------------+----------+-------
2016-04-12 | www.domain1.com | 2016-04-12 | 1231 | 23423
2016-04-13 | www.domain1.com | 2016-04-13 | 1374 | 26482
2016-04-14 | www.domain1.com | 2016-04-13 | 1374 | 26482
2016-04-15 | www.domain1.com | 2016-04-13 | 1374 | 26482
2016-04-16 | www.domain1.com | 2016-04-13 | 1374 | 26482
2016-04-17 | www.domain1.com | 2016-04-17 | 1262 | 21493
(6 rows)
Bạn sẽ phải chọn ngày bắt đầu và ngày kết thúc theo yêu cầu của mình. Truy vấn có thể khá tốn kém (bạn đã đề cập về hàng tỷ khoảng trống) vì vậy hãy áp dụng nó một cách thận trọng (thử nghiệm trên một tập hợp con dữ liệu nhỏ hơn hoặc thực hiện theo từng giai đoạn).
Trong trường hợp không có generate_series()
bạn có thể tạo máy phát điện của riêng bạn. Đây là một ví dụ thú vị
. Các chế độ xem từ bài báo được trích dẫn có thể được sử dụng thay vì generate_series()
. Ví dụ:nếu bạn cần khoảng thời gian '2016-04-12' + 5 days
:
select distinct on (domain, new_date) *
from (
select '2016-04-12'::date+ n new_date
from generator_16
where n < 6
) s
left join a_table t on date <= new_date
order by domain, new_date, date desc;
bạn sẽ nhận được kết quả tương tự như trong ví dụ đầu tiên.