【问题标题】:postgres - calculating cumulative sum based on conditionspostgres - 根据条件计算累积和
【发布时间】:2019-09-13 02:15:23
【问题描述】:

我有一个名为asset_reporting 的数据库表,看起来像这样

asset_id      asset_type       entered_at             exited_at         site_id
  100           Cage       2019-05-02 10:00:00    2019-05-04 10:00:00     25
  102           Cage       2019-05-03 10:00:00         null               25
  103         Container    2019-05-01 10:00:00    2019-05-03 10:00:00     25

我需要计算资产在给定时间范围内在特定站点的运行总时间。假设我正在查看的时间范围是从 2019-05-01 到 2019-05-05,我需要的输出低于每天

     day       asset_type        count
 2019-05-01      Cage              0
 2019-05-01    Container           1
 2019-05-02      Cage              1
 2019-05-02    Container           1
 2019-05-03      Cage              2
 2019-05-03    Container           1
 2019-05-04      Cage              2
 2019-05-04    Container           0
 2019-05-05      Cage              1
 2019-05-05    Container           0

到目前为止,我收到了以下查询。我无法弄清楚如何保持资产在站点上的总天数

select date(ar.entered_at) as day, asset_type, count(*) from asset_reporting ar
group by day,asset_type

下面是上述查询的输出。请注意,它不是我预期的上述输出。

     day       asset_type        count
 2019-05-01      Cage              0
 2019-05-01    Container           1
 2019-05-02      Cage              1
 2019-05-02    Container           0
 2019-05-03      Cage              1
 2019-05-03    Container           0
 2019-05-04      Cage              0
 2019-05-04    Container           0
 2019-05-05      Cage              0
 2019-05-05    Container           0

【问题讨论】:

    标签: postgresql grouping cumulative-sum


    【解决方案1】:

    我们可以使用日历表的方法来解决这个问题:

    WITH dates AS (
        SELECT '2019-05-01'::date AS day UNION ALL
        SELECT '2019-05-02'::date UNION ALL
        SELECT '2019-05-03'::date UNION ALL
        SELECT '2019-05-04'::date UNION ALL
        SELECT '2019-05-05'::date
    )
    
    SELECT
        d.day,
        at.asset_type,
        COUNT(ar.asset_type) AS count
    FROM dates d
    CROSS JOIN (SELECT DISTINCT asset_type FROM asset_reporting) at
    LEFT JOIN asset_reporting ar
        ON at.asset_type = ar.asset_type AND
           (d.day >= ar.entered_at::date OR ar.entered_at IS NULL) AND
           (d.day <= ar.exited_at::date OR ar.exited_at IS NULL)
    GROUP BY
        d.day,
        at.asset_type
    ORDER BY
        d.day,
        at.asset_type;
    

    Demo

    【讨论】:

      猜你喜欢
      • 2021-04-23
      • 1970-01-01
      • 2020-09-30
      • 2014-02-16
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多