【问题标题】:How to find sum of a column between a given date range, where the table has only start date and end date如何在给定日期范围内查找列的总和,其中表格只有开始日期和结束日期
【发布时间】:2012-04-19 21:06:26
【问题描述】:

我有一个这样的 postgresql 表 userDistributions:
user_id, start_date, end_date, project_id, distribution

我需要编写一个查询,其中给定的日期范围和用户 ID 的输出应该是该给定用户每天所有分布的总和。
所以输入的输出应该是这样的:'2-2-2012' - '2-4-2012',一些用户 ID:
Date SUM(Distribution)
2-2-2012 12
2-3-2012 15
2-4-2012 34

一个用户在许多项目中都有分布,所以我需要对每天所有项目中的分布求和,然后输出当天的总和。

我的问题是我应该针对什么分组?如果我有一个字段作为日期(而不是 start_date 和 end_date),那么我可以写类似
select date, SUM(distributions) from userDistributions group by date;
但在这种情况下,我不知道该怎么做。感谢您的帮助。

【问题讨论】:

  • 您的数据库需要一个日历表。它使这类查询变得更加容易。
  • @GordonLinoff:你几乎不需要使用 PostgreSQL 的日历表,generate_series 更好。
  • 您是否希望看到包含 0 个项目的日期的数据?
  • @Mike 很好,但没必要。

标签: sql postgresql


【解决方案1】:

使用generate_series 生成您的日期,如下所示:

select dt.d::date, sum(u.distributions)
from userdistributions u
join generate_series('2012-02-02'::date, '2012-02-04'::date, '1 day') as dt(d)
  on dt.d::date between u.start_date and u.end_date
group by dt.d::date

您的日期格式不明确,所以我猜是在将其转换为 ISO 8601 时。

【讨论】:

  • 这太棒了,generate_series 是 postgres 特定的还是所有其他 DBMS 的标准?
  • @Rohit:我很确定它是 PostgreSQL 特有的,但它非常有用,它真的应该在标准中。
  • @Rohitchauhan 这是一个非标准的 PostgreSQL 函数。
【解决方案2】:

这很像@mu 的回答。
但是,要涵盖没有匹配的日子,您应该使用 LEFT JOIN:

SELECT d.d::date, sum(u.distributions) AS dist_sum
FROM   generate_series('2012-02-02'::date, '2012-02-04'::date, '1 day') AS d(d)
LEFT   JOIN userdistributions u ON d.d::date BETWEEN u.start_date AND u.end_date
GROUP  BY 1

【讨论】:

  • 是的,这处理了显示日期但没有匹配的用户分布记录的“会很好”的情况。
猜你喜欢
  • 2020-12-23
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多