postgresql 使用CTE创建透视表

9njqaruj  于 2022-12-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(216)

我有一张table:

任务

使用CTE创建数据透视表。
统计几年中每个月发出的订单:2011年至2013年。最后表格应包括四个字段:invoice_monthyear_2011year_2012year_2013。月份字段必须将月份存储为1到12之间的数字。如果任何月份都没有下订单,则该月份的数字仍应包括在表中。
我可以使用以下查询解决此任务:

WITH year11
AS (
    SELECT EXTRACT(MONTH FROM invoice.invoice_date::TIMESTAMP) AS invoice_month
        ,COUNT(*) AS orders
    FROM invoice
    WHERE EXTRACT(YEAR FROM invoice.invoice_date::TIMESTAMP) = 2011
    GROUP BY invoice_month
    )
    ,year12
AS (
    SELECT EXTRACT(MONTH FROM invoice.invoice_date::TIMESTAMP) AS invoice_month
        ,COUNT(*) AS orders
    FROM invoice
    WHERE EXTRACT(YEAR FROM invoice.invoice_date::TIMESTAMP) = 2012
    GROUP BY invoice_month
    )
    ,year13
AS (
    SELECT EXTRACT(MONTH FROM invoice.invoice_date::TIMESTAMP) AS invoice_month
        ,COUNT(*) AS orders
    FROM invoice
    WHERE EXTRACT(YEAR FROM invoice.invoice_date::TIMESTAMP) = 2013
    GROUP BY invoice_month
    )
SELECT year11.invoice_month
    ,year11.orders AS year_2011
    ,year12.orders AS year_2012
    ,year13.orders AS year_2013
FROM year11
INNER JOIN year12 ON year11.invoice_month = year12.invoice_month
INNER JOIN year13 ON year11.invoice_month = year13.invoice_month

但是这个请求看起来太大了(或者不是?)。
1.在我的查询中使用CTE可以改进什么(我应该改进吗?)
1.其他工具来解决这个任务又快又漂亮?

x4shl7ld

x4shl7ld1#

我发现使用筛选聚合生成透视表要容易得多:

SELECT extract(month from inv.invoice_date) AS invoice_month
       COUNT(*) filter (where extract(year from inv.invoice_date) = 2011) AS orders_2011,
       COUNT(*) filter (where extract(year from inv.invoice_date) = 2012) AS orders_2012,
       COUNT(*) filter (where extract(year from inv.invoice_date) = 2013) AS orders_2013
FROM invoice inv
WHERE inv.invoice_date >= date '2011-01-01'
  AND inv.invoice_date < date '2014-01-01'
GROUP BY invoice_month

相关问题