PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Số lượng hàng truy vấn được phân tách theo phạm vi ngày

crosstab() hàm có hai tham số.

Nên hoạt động như thế này, để nhận các giá trị cho năm 2012:

SELECT * FROM crosstab(
     $$SELECT testname, to_char(last_update, 'mon_YYYY'), count(*)::int AS ct
        FROM   tests
        WHERE  current_status = 'FAILED'
        AND    last_update >= '2012-01-01 0:0'
        AND    last_update <  '2013-01-01 0:0'  -- proper date range!
        GROUP  BY 1,2
        ORDER  BY 1,2$$

    ,$$VALUES
      ('jan_2012'::text), ('feb_2012'), ('mar_2012')
    , ('apr_2012'), ('may_2012'), ('jun_2012')
    , ('jul_2012'), ('aug_2012'), ('sep_2012')
    , ('oct_2012'), ('nov_2012'), ('dec_2012')$$)
AS ct (testname  text
   , jan_2012 int, feb_2012 int, mar_2012 int
   , apr_2012 int, may_2012 int, jun_2012 int
   , jul_2012 int, aug_2012 int, sep_2012 int
   , oct_2012 int, nov_2012 int, dec_2012 int);

Tìm lời giải thích chi tiết trong câu hỏi có liên quan này.

Tôi đã không kiểm tra. Như @Craig đã nhận xét, các giá trị mẫu sẽ hữu ích.
Đã được kiểm tra ngay bây giờ với trường hợp thử nghiệm của riêng tôi.

Không hiển thị giá trị NULL

Vấn đề chính (những tháng không có hàng sẽ không hiển thị) được ngăn chặn bởi crosstab() hàm với hai tham số.

Bạn không thể sử dụng COALESCE trong truy vấn bên trong, vì NULL các giá trị được chèn bởi crosstab() chính nó. Bạn có thể ...

1. Gói toàn bộ nội dung vào một truy vấn con:

SELECT testname
      ,COALESCE(jan_2012, 0) AS jan_2012
      ,COALESCE(feb_2012, 0) AS feb_2012
      ,COALESCE(mar_2012, 0) AS mar_2012
      , ...
FROM (
    -- query from above)
    ) x;

2. LEFT JOIN truy vấn chính cho danh sách đầy đủ các tháng.

Trong trường hợp này, bạn không cần tham số thứ hai theo định nghĩa.
Đối với phạm vi lớn hơn, bạn có thể sử dụng generate_series() để tạo các giá trị.

SELECT * FROM crosstab(
     $$SELECT t.testname, m.mon, count(x.testname)::int AS ct
       FROM  (
          VALUES
           ('jan_2012'::text), ('feb_2012'), ('mar_2012')
          ,('apr_2012'), ('may_2012'), ('jun_2012')
          ,('jul_2012'), ('aug_2012'), ('sep_2012')
          ,('oct_2012'), ('nov_2012'), ('dec_2012')
       ) m(mon)
       CROSS JOIN (SELECT DISTINCT testname FROM tests) t
       LEFT JOIN (
          SELECT testname
                ,to_char(last_update, 'mon_YYYY') AS mon
          FROM   tests
          WHERE  current_status = 'FAILED'
          AND    last_update >= '2012-01-01 0:0'
          AND    last_update <  '2013-01-01 0:0'  -- proper date range!
          ) x USING (mon)
       GROUP  BY 1,2
       ORDER  BY 1,2$$
     )
AS ct (testname  text
   , jan_2012 int, feb_2012 int, mar_2012 int
   , apr_2012 int, may_2012 int, jun_2012 int
   , jul_2012 int, aug_2012 int, sep_2012 int
   , oct_2012 int, nov_2012 int, dec_2012 int);

Trường hợp thử nghiệm với dữ liệu mẫu

Đây là một trường hợp thử nghiệm với một số dữ liệu mẫu mà OP không cung cấp được. Tôi đã sử dụng cái này để kiểm tra và làm cho nó hoạt động.

CREATE TEMP TABLE tests (
  id             bigserial PRIMARY KEY
 ,testname       text NOT NULL
 ,last_update    timestamp without time zone NOT NULL DEFAULT now()
 ,current_status text NOT NULL
 );

INSERT INTO tests (testname, last_update, current_status)
VALUES
  ('foo', '2012-12-05 21:01', 'FAILED')
 ,('foo', '2012-12-05 21:01', 'FAILED')
 ,('foo', '2012-11-05 21:01', 'FAILED')
 ,('bar', '2012-02-05 21:01', 'FAILED')
 ,('bar', '2012-02-05 21:01', 'FAILED')
 ,('bar', '2012-03-05 21:01', 'FAILED')
 ,('bar', '2012-04-05 21:01', 'FAILED')
 ,('bar', '2012-05-05 21:01', 'FAILED');



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sắp xếp / đối chiếu / thứ tự không chính xác với khoảng trắng trong Postgresql 9.4

  2. Tôi đang gặp sự cố khi đẩy ứng dụng rails của mình lên Heroku / cài đặt gem 'pg'?

  3. PG ::Lỗi:LỖI:mã hóa mới (UTF8) không tương thích

  4. 'Không thể tìm thấy pg-0.12.2 trong bất kỳ nguồn nào' khi chạy rspec

  5. Tại sao PostgreSQL không thể thực hiện FULL JOIN đơn giản này?