【问题标题】:Group query results by month and year in postgresql with emply month sum在 postgresql 中按月和年对查询结果进行分组,并使用月总和
【发布时间】:2020-06-27 15:01:58
【问题描述】:

基于此answerBurak Arslan

SELECT date_trunc('month', txn_date) AS txn_month, sum(amount) as monthly_sum
    FROM yourtable
GROUP BY txn_month

有没有办法让查询中没有结果显示的月份?

假设我有:

id      transDate     Product Qty
1234    04/12/2019    ABCD    2     
1245    04/05/2019    ABCD    1
1231    02/07/2019    ABCD    6

我还需要第三个月返回 0 值

MonthYear  totalQty
02/2019    6
03/2019    0
04/2019    3

谢谢,

---- 更新 ---

这是从当前日期开始最近 24 个月的最终查询。年和月准备好任何图表。

感谢@a_horse_with_no_name

SELECT 
    --ONLY USE THE NEXT LINE IF YOU NEED TO HAVE THE ID IN YOUR RESULT
    CASE WHEN t."ItemId" IS NULL THEN 10607 ELSE t."ItemId" END AS "ItemId",
    TO_CHAR(y."transactionDate", 'yyyy-mm-dd') AS txn_month,
    TO_CHAR(y."transactionDate", 'yyyy') AS "Year",
    TO_CHAR(y."transactionDate", 'Mon') AS "Month",
    -coalesce(SUM(t."transactionQty"),0) AS "TotalSold"
FROM generate_series(
    TO_CHAR(CURRENT_DATE - INTERVAL '24 month', 'yyyy-mm-01')::date , 
    TO_CHAR(CURRENT_DATE, 'yyyy-mm-01')::date, 
    INTERVAL '1 month') as y("transactionDate")
  LEFT JOIN "ItemTransactions" AS t 
         ON date_trunc('month', t."transactionDate") = y."transactionDate"
        AND t."ItemTransactionTypeId" = 1
        AND t."ItemId" = 10607
GROUP BY txn_month, "Year", "Month", t."ItemId"
ORDER BY txn_month ASC;

示例输出

ItemId  txn_month   Year    Month   TotalSold
10607   2018-03-01  2018    Mar     2
10607   2018-04-01  2018    Apr     0
10607   2018-05-01  2018    May     8
10607   2018-06-01  2018    Jun     12
10607   2018-07-01  2018    Jul     6
10607   2018-08-01  2018    Aug     4
10607   2018-09-01  2018    Sep     6
10607   2018-10-01  2018    Oct     8
10607   2018-11-01  2018    Nov     4
10607   2018-12-01  2018    Dec     0
10607   2019-01-01  2019    Jan     2
10607   2019-02-01  2019    Feb     3
10607   2019-03-01  2019    Mar     4
10607   2019-04-01  2019    Apr     1
10607   2019-05-01  2019    May     4
10607   2019-06-01  2019    Jun     3
10607   2019-07-01  2019    Jul     5
10607   2019-08-01  2019    Aug     6
10607   2019-09-01  2019    Sep     6
10607   2019-10-01  2019    Oct     6
10607   2019-11-01  2019    Nov     3
10607   2019-12-01  2019    Dec     0
10607   2020-01-01  2020    Jan     4
10607   2020-02-01  2020    Feb     2
10607   2020-03-01  2020    Mar     0

【问题讨论】:

  • 与您的问题无关,但是:您应该真正避免使用那些可怕的带引号的标识符。他们的麻烦比他们的价值要多得多。 wiki.postgresql.org/wiki/…
  • 感谢@a_horse_with_no_name 的输入。在我使用 Sequelize 构建了所有模型并从 MySql 切换到 Postgres 后,我意识到了这个问题。我应该提前设置它。现在我有点坚持了!啊。

标签: postgresql


【解决方案1】:

左连接到月份列表:

SELECT t.txn_month, 
       coalesce(sum(yt.amount),0) as monthly_sum
FROM generate_series(date '2019-02-01', date '2019-04-01', interval '1 month') as t(txn_month)
  left join yourtable yt on date_trunc('month', yt.transdate) = t.txn_month
GROUP BY t.txn_month

Online example


在您的实际查询中,您需要将条件从 WHERE 子句移至 JOIN 条件。将它们放入 WHERE 子句会将外连接重新变为内连接:

SELECT t."ItemId",
       y."transactionDate" AS txn_month,
       -coalesce(SUM(t."transactionQty"),0) AS "TotalSold"
FROM generate_series(date '2018-01-01', date '2020-04-01', INTERVAL '1 month') as y("transactionDate")
  LEFT JOIN "ItemTransactions" AS t 
         ON date_trunc('month', t."transactionDate") = y."transactionDate"
        AND t."ItemTransactionTypeId" = 1
        AND t."ItemId" = 10606
-- this WHERE clause isn't really needed because of the date values provided to generate_series()
WHERE AND y."transactionDate" >= NOW() - INTERVAL '2 year'
GROUP BY txn_month, t."ItemId"
ORDER BY txn_month DESC;

【讨论】:

  • 出于某种原因,当我 LEFT JOIN 我的表时,我仍然没有得到零。 ` SELECT t."ItemId", y."transactionDate" AS txn_month, SUM(t."transactionQty")*-1 AS "TotalSold" FROM generate_series(date '2018-01-01', date '2020-04-01 ', INTERVAL '1 month') as y("transactionDate") LEFT JOIN "ItemTransactions" AS t ON date_trunc('month', t."transactionDate") = y."transactionDate" WHERE t."ItemTransactionTypeId" = 1 AND t."ItemId" = 10606 AND y."transactionDate" >= NOW() - INTERVAL '2 year' GROUP BY txn_month, t."ItemId" ORDER BY txn_month DESC; ` generated_series 显示 *
  • 谢谢@a_horse_with_no_name。它现在就像一个魅力。我只需要做一点小改动就可以确保在我的第一列 CASE WHEN t."ItemId" IS NULL THEN 10606 ELSE t."ItemId" END AS "ItemId" 中获得 ID
猜你喜欢
  • 2013-07-03
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
相关资源
最近更新 更多