【问题标题】:Sum column value and group dates by month with Postgres使用 Postgres 按月汇总列值和分组日期
【发布时间】:2019-02-21 18:42:57
【问题描述】:

我的 Postgres DB 中有一个表,看起来像这样:

date          duration
2018-05-10      10
2018-05-12      15
2018-06-01      10
2018-06-02      20
2019-01-01      5
2019-01-02      15
2019-04-01      10

我希望将每个月的值相加,并按年、月和月数将它们分组为如下所示:

year    month    month_number   monthly_sum
2018    May         5              25
2018    June        6              30
2019    Jan         1              20
2019    Apr         4              10

最后得到如下查询:

SELECT 
  to_char(date_trunc('month', date), 'YYYY') AS year,
  to_char(date_trunc('month', date), 'Mon') AS month,
  to_char(date_trunc('month', date), 'MM') AS month_number,
  sum(duration) AS monthly_sum
FROM timesheet 
GROUP BY year, month, month_number

它工作得很好,我的问题是:这个查询被认为是坏的吗?如果我喜欢.. 100k 行,它会影响性能吗?我听说使用 to_char 不如 date_trunc,这是我在这里试图避免的,我只是将 date_trunc 包裹在一个 to_char 中。 另外,GROUP BY 子句中包含三个值,它会影响什么吗?

【问题讨论】:

标签: sql postgresql


【解决方案1】:

查询还不错,但是可以简化一下。

SELECT to_char(date_trunc('month', date), 'YYYY') AS year,
       to_char(date_trunc('month', date), 'Mon') AS month,
       to_char(date_trunc('month', date), 'MM') AS month_number,
       sum(duration) AS monthly_sum
FROM timesheet 
GROUP BY date_trunc('month', date);

从性能的角度来看,较短的GROUP BY 键对性能的影响很小,但我不会担心。

【讨论】:

    【解决方案2】:

    使用函数并相应地使用它们进行分组可能会降低性能。为此目的,最好使用带有适当索引的Calendar 表,这样您就不需要在每个表上处理此类问题。

    Check Thisthis (Calendar Table)

    【讨论】:

      【解决方案3】:

      由于您的查询没有任何过滤条件,它总是读取表的所有行:这是对性能的主要影响。如果你有过滤条件,你可能会更好地拥有正确的索引。

      话虽如此,您提取年份和月份的方式可能会略有改进,正如此处的其他答案所示,但这对查询的性能影响不大。

      总之,在没有过滤条件的情况下,您的查询接近最优。

      【讨论】:

      • 如果我要添加一个过滤器来仅查询特定年份,WHERE 子句会去哪里?我不能只去...FROM timesheet WHERE YEAR = 2019,因为列年份不存在
      • WHERE extract(year from date) = 2019
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      相关资源
      最近更新 更多