date
là một từ dành riêng
trong SQL chuẩn và tên của một kiểu dữ liệu trong PostgreSQL. PostgreSQL cho phép nó làm định danh, nhưng điều đó không khiến nó trở thành một ý tưởng hay. Tôi sử dụng thedate
thay vào đó là tên cột.
Đừng dựa vào việc không có khoảng trống trong ID đại diện. Đó hầu như luôn luôn là một ý tưởng tồi. Coi một ID như vậy là số duy nhất không có ý nghĩa , ngay cả khi nó dường như mang một số thuộc tính khác hầu hết thời gian .
Trong trường hợp cụ thể này, như @ Clodoaldo đã nhận xét
, thedate
dường như là một khóa chính hoàn hảo và cột id
chỉ là mấu chốt - mà tôi đã xóa:
CREATE TEMP TABLE tbl (thedate date PRIMARY KEY, rainfall numeric);
INSERT INTO tbl(thedate, rainfall) VALUES
('2002-05-06', 110.2)
, ('2002-05-07', 56.6)
, ('2002-05-09', 65.6)
, ('2002-05-10', 75.9);
Truy vấn
Bảng đầy đủ theo truy vấn:
SELECT x.thedate, t.rainfall -- rainfall automatically NULL for missing rows
FROM (
SELECT generate_series(min(thedate), max(thedate), '1d')::date AS thedate
FROM tbl
) x
LEFT JOIN tbl t USING (thedate)
ORDER BY x.thedate
Tương tự như những gì @a_horse_with_no_name
đã đăng, nhưng được đơn giản hóa và bỏ qua id
được lược bớt .
Điền vào khoảng trống giữa ngày đầu tiên và ngày cuối cùng được tìm thấy trong bảng. Nếu có thể có khoảng cách dẫn đầu / tụt hậu, hãy mở rộng tương ứng. Bạn có thể sử dụng date_trunc()
như @Clodoaldo
đã chứng minh - nhưng truy vấn của anh ấy bị lỗi cú pháp và có thể đơn giản hơn.
CHÈN các hàng bị thiếu
Cách nhanh nhất và dễ đọc nhất để làm điều đó là NOT EXISTS
chống bán tham gia.
INSERT INTO tbl (thedate, rainfall)
SELECT x.thedate, NULL
FROM (
SELECT generate_series(min(thedate), max(thedate), '1d')::date AS thedate
FROM tbl
) x
WHERE NOT EXISTS (SELECT 1 FROM tbl t WHERE t.thedate = x.thedate)