后12个月后计数

发布于 2025-02-03 01:49:48 字数 2310 浏览 1 评论 0原文

我正在计算加入多个表后的最后12个月计数,我的预期输出可以正常工作,但这不是我想要的吗?我想添加另一列名称为“当前月”,所以基本想法是,如果我看到了一个月的报告 May ,那么它将从去年的5月到今年开始4月和5月作为当月,总计13列计数。我的直觉说窗口查询将帮助我解决这个问题,但是我现在确定如何做到这一点。

select
c.name,
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'January'  THEN 1  END) as "January",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'February' THEN 1  END) as "February",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'March' THEN 1  END) as "March",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'April' THEN 1  END) as "April",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'May' THEN 1  END) as "May",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'June' THEN 1  END) as "June",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'July' THEN 1  END) as "July",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'August' THEN 1  END) as "August",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'September' THEN 1  END) as "September",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'October' THEN 1  END) as "October",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'November' THEN 1  END) as "November",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'December' THEN 1  END) as "December"
from analytics_outbox mo 
inner join analytics_outbox_recipient mor on mor.analytics_outbox_id = mo.id
inner join customer c on c.id = mo.customer_id
group by c.name

当前输出:

name                              |january|february|march |april  |may    |june|july|august|september|october|november|december|
----------------------------------+-------+--------+------+-------+-------+----+----+------+---------+-------+--------+--------+
ABC                               |       |        |     1|      2|       |    |    |      |         |       |        |        |
DEF                               |     11|      24|    34|     32|     19|    |    |      |         |       |        |        |
GEH                               |      9|       3|     7|     18|     22|    |    |      |         |       |        |        |
IJK                               |       |        |      |      1|       |    |    |      |         |       |        |        |

I am calculating the last 12-months count after joining multiple tables, my expected output is working is OK but it is not what I want?. I want to add another column with the name "Current Month", so the basic idea is if I see a report for the month May, then it will start from Last year's May till This year's April and May as Current Month, total 13 columns counts. My intuition says window query will help me out on this, but I am now sure how I can do that.

select
c.name,
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'January'  THEN 1  END) as "January",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'February' THEN 1  END) as "February",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'March' THEN 1  END) as "March",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'April' THEN 1  END) as "April",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'May' THEN 1  END) as "May",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'June' THEN 1  END) as "June",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'July' THEN 1  END) as "July",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'August' THEN 1  END) as "August",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'September' THEN 1  END) as "September",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'October' THEN 1  END) as "October",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'November' THEN 1  END) as "November",
  SUM(case when RTRIM(TO_CHAR(mor.sent_at , 'Month')) = 'December' THEN 1  END) as "December"
from analytics_outbox mo 
inner join analytics_outbox_recipient mor on mor.analytics_outbox_id = mo.id
inner join customer c on c.id = mo.customer_id
group by c.name

Current Output:

name                              |january|february|march |april  |may    |june|july|august|september|october|november|december|
----------------------------------+-------+--------+------+-------+-------+----+----+------+---------+-------+--------+--------+
ABC                               |       |        |     1|      2|       |    |    |      |         |       |        |        |
DEF                               |     11|      24|    34|     32|     19|    |    |      |         |       |        |        |
GEH                               |      9|       3|     7|     18|     22|    |    |      |         |       |        |        |
IJK                               |       |        |      |      1|       |    |    |      |         |       |        |        |

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半﹌身腐败 2025-02-10 01:49:49

动态结果列名仅使用动态SQL才有可能。

这应该有效地完成工作,保存动态列名:

SELECT c.name
     , to_char(t.mon, 'Month YYYY') AS report_month
     , count(*) FILTER (WHERE mor.sent_at >= t.mon - interval '12 mon' AND mor.sent_at <  t.mon - interval '11 mon') AS mon1
     , count(*) FILTER (WHERE mor.sent_at >= t.mon - interval '11 mon' AND mor.sent_at <  t.mon - interval '10 mon') AS mon2
     , count(*) FILTER (WHERE mor.sent_at >= t.mon - interval '10 mon' AND mor.sent_at <  t.mon - interval '09 mon') AS mon3
     -- etc.
FROM   analytics_outbox           mo
JOIN   analytics_outbox_recipient mor ON mor.analytics_outbox_id = mo.id
JOIN   customer                   c   ON c.id = mo.customer_id
    , (SELECT date_trunc('month', now())) AS t(mon)    -- add once for ease of use
GROUP  BY 1;

这将未更改的值从send_at与常数值(计算一次)进行比较,该值比在比较之前通过多个函数运行每个值便宜。

由于缺少输入而无法解析的时区和TIMESTAMP timestamp timestamp 可能的转角案例问题。

Dynamic result column names are only possible with dynamic SQL.

This should do the job efficiently, save the dynamic column names:

SELECT c.name
     , to_char(t.mon, 'Month YYYY') AS report_month
     , count(*) FILTER (WHERE mor.sent_at >= t.mon - interval '12 mon' AND mor.sent_at <  t.mon - interval '11 mon') AS mon1
     , count(*) FILTER (WHERE mor.sent_at >= t.mon - interval '11 mon' AND mor.sent_at <  t.mon - interval '10 mon') AS mon2
     , count(*) FILTER (WHERE mor.sent_at >= t.mon - interval '10 mon' AND mor.sent_at <  t.mon - interval '09 mon') AS mon3
     -- etc.
FROM   analytics_outbox           mo
JOIN   analytics_outbox_recipient mor ON mor.analytics_outbox_id = mo.id
JOIN   customer                   c   ON c.id = mo.customer_id
    , (SELECT date_trunc('month', now())) AS t(mon)    -- add once for ease of use
GROUP  BY 1;

This compares unaltered values from sent_at to a constant value (computed once), which is cheaper than running each value through multiple functions before comparison.

Possible corner case issues with time zone and timestamp vs. timestamptz unresolved due to missing input.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文