【问题标题】:Count Number of Records that Existed on a Date计算某个日期存在的记录数
【发布时间】:2017-05-18 15:57:52
【问题描述】:

我正在尝试计算一个时间段内的不同记录数,按天分组/汇总。

在此示例中,有客户服务票在某个日期打开,然后在以后关闭。我试图找出每天在任何时间点有多少张票是开放的(否则,closed status 是相对于该日期的未来)。这是我在 MySQL 中使用的查询:

SELECT `cal`.`dt`,
   COUNT(DISTINCT `sub_query`.`id`)
FROM `calendar_table` AS `cal`
LEFT JOIN
  (SELECT `inc`.`id`,
      `inc`.`created_at`,
      `inc_stat`.`updated_at`
   FROM `incidents` AS `inc`
   JOIN `incident_statuses` AS `inc_stat` ON `inc_stat`.`incident_id` = 
`inc`.`id`
   WHERE `inc_stat`.`status` LIKE 'Closed') AS `sub_query` ON (`sub_query`.`created_at` >= `cal`.`dt` AND `sub_query`.`updated_at` <= `cal`.`dt`)

 WHERE `cal`.`dt` >= '2017-01-01'
 AND `cal`.`dt` <= NOW()
 GROUP BY `cal`.`dt`

日历表只是一个“辅助”表,其中包含 2010-2020 年正确格式的日期。

calendar_table cal 数据示例

id       dt
1        2017-01-01
2        2017-01-02
3        2017-01-03
...      ...

样本事件包括数据

id     created_at
1      2017-01-01 08:45:01
1      2017-01-01 08:55:01
...    ...

event_statuses inc_stat 数据示例

id        incident_id      status         updated_at
1         1                Closed         2017-01-02
2         2                Closed         2017-01-04
...       ...              ...            ...

子查询以这种格式正确生成数据:

id         created_at         updated_at
1          2017-01-01         2017-01-02
2          2017-01-01         2017-01-04
3          2017-01-04         2017-01-05

我想要的输出是这样的:

dt                    count(distinct `subquery`.`id`)
2017-01-01            2            
2017-01-02            2
2017-01-03            1
2017-01-04            3
2017-01-05            1

我意识到这在带有 FOR 循环的编程语言中会简单得多,但是有没有人指导如何仅使用 SQL 来做到这一点?

【问题讨论】:

  • 您能否也显示输入表中的示例数据?
  • 当然 - 请查看更新后的答案更详细。它是一个简单的多对一关系,其中一个事件可以有许多事件状态。我对“已关闭”状态以及上次更新已关闭状态的日期感兴趣
  • @CDD 你改变了你的问题,我不知道......
  • @aendeerei 抱歉,我刚刚添加了更多细节。核心问题和基础 SQL 查询还是一样的。
  • @CDD 没问题。

标签: mysql sql date reporting


【解决方案1】:

我不确定您使用的是什么数据库,但我认为您只需要以下内容:

SELECT CONVERT(date,inc.created_at), COUNT(*)
  FROM incidents inc
 WHERE inc.created_at BETWEEN '2017-01-01' AND NOW()
 GROUP BY CONVERT(date,inc.created_at)
 ORDER BY 1

【讨论】:

  • 谢谢乔纳森 - 这确实让我知道每天打开的事件数量,我可以逆向找到每天关闭的数字,但我仍然无法合并这些以找到数字在任何给定日期打开的事件。我还编辑了问题以反映我正在使用 MySQL - 对查询的小改动正在反转 CONVERT() 参数。
【解决方案2】:

试试这个:

SELECT 
    cal.dt
    , COUNT(IFNULL(inc_stat.id, 0)) as cntIncStat
FROM calendar_table AS cal
LEFT JOIN incidents AS inc ON inc.created_at = cal.dt
LEFT JOIN incident_statuses AS inc_stat ON inc_stat.incident_id = inc.id
GROUP BY cal.dt
HAVING
    inc_stat.status = 'Closed'
    AND cal.dt >= '2017-01-01'
    AND cal.dt <= NOW()
;

【讨论】:

  • @CDD 将 COUNT 更改为显示 0 如果 sub_query.idNULL
  • 谢谢 - 但是我仍然在 2017 年 1 月 1 日和今天之间的每一天得到一行结果,计数为零/零,就像我对原始查询所做的那样。我还尝试在第 15 行将 AND 更改为 OR,结果是一样的。
  • @CDD 您希望每天有一条记录,显示incident_statuses 的计数 (>=0),不是吗?!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2016-05-18
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多