2012-11-16 24 views
7

Những gì tôi muốn nhận được là một số liệu thống kê với mỗi tháng từ một generate_series và tổng của số đếm trong mỗi tháng. SQL này hoạt động trong PostgreSQL 9.1:Tham gia truy vấn đếm trên một generate_series trong postgres và cũng lấy Null-giá trị là "0"

SELECT (to_char(serie,'yyyy-mm')) AS year, sum(amount)::int AS eintraege FROM (
    SELECT 
     COUNT(mytable.id) as amount, 
     generate_series::date as serie 
     FROM mytable 

    RIGHT JOIN generate_series( 

     (SELECT min(date_from) FROM mytable)::date, 
     (SELECT max(date_from) FROM mytable)::date, 
     interval '1 day') ON generate_series = date(date_from) 
     WHERE version = 1 
     GROUP BY generate_series  
     ) AS foo 
    GROUP BY Year 
    ORDER BY Year ASC; 

Và đây là kết quả của tôi

"2006-12" | 4 
"2007-02" | 1 
"2007-03" | 1 

Nhưng những gì tôi muốn nhận được là sản lượng này ("0" giá trị trong tháng Giêng):

"2006-12" | 4 
"2007-01" | 0 
"2007-02" | 1 
"2007-03" | 1 

Vì vậy, nếu có một tháng không có id nó nên được liệt kê tuy nhiên. Bất kỳ ý tưởng nào để giải quyết vấn đề này?

Dưới đây là một số dữ liệu mẫu:

drop table if exists mytable; 
create table mytable(id bigint, version smallint, date_from timestamp without time zone); 
insert into mytable(id, version, date_from) values 

('4084036', '1', '2006-12-22 22:46:35'), 
('4084938', '1', '2006-12-23 16:19:13'), 
('4084938', '2', '2006-12-23 16:20:23'), 
('4084939', '1', '2006-12-23 16:29:14'), 
('4084954', '1', '2006-12-23 16:28:28'), 
('4250653', '1', '2007-02-12 21:58:53'), 
('4250657', '1', '2007-03-12 21:58:53') 
; 
+1

Như mọi khi, định nghĩa bảng 'mytable' phải nằm trong câu hỏi của bạn. Và một số giá trị ví dụ để đi với nó sẽ sưng lên. –

Trả lời

16

Untangled, đơn giản và cố định, nó có thể trông như thế này:

SELECT to_char(s.tag,'yyyy-mm') AS monat 
     ,count(t.id) AS eintraege 
FROM (
    SELECT generate_series(min(date_from)::date 
         ,max(date_from)::date 
         ,interval '1 day' 
     )::date AS tag 
    FROM mytable t 
    ) s 
LEFT JOIN mytable t ON t.date_from::date = s.tag AND t.version = 1 
GROUP BY 1 
ORDER BY 1; 

Trong số tất cả các tiếng ồn, định danh gây hiểu lầm và định dạng độc đáo các vấn đề thực tế là ẩn tại đây:

WHERE version = 1 

Khi bạn sử dụng đúng cách RIGHT JOIN, bạn đã vô hiệu hóa nỗ lực bằng cách thêm mệnh đề WHERE yêu cầu giá trị khác biệt từ mytable - chuyển đổi RIGHT JOIN thành hiệu quả JOIN.

Kéo điều khoản xuống điều kiện JOIN để thực hiện công việc này.

Tôi đã đơn giản hóa một số thứ khác.

+0

Cảm ơn bạn rất nhiều vì câu trả lời của bạn và đặc biệt là lời giải thích! Câu trả lời của bạn giải quyết được vấn đề. – zehpunktbarron

Các vấn đề liên quan