【问题标题】:SQL query to find the changes in status throughout the daySQL查询查找全天状态的变化
【发布时间】:2019-05-21 16:52:39
【问题描述】:

我有一个名为STATUS_HISTORY的数据库表

  1. ID-记录的ID(ID和REV的组合是唯一的)
  2. REV - 修订 ID,如果任何记录发生更改,则会创建一个具有递增修订 ID 的新条目
  3. STATUS - 它可以包含三个值

    • 打开
    • 关闭
    • 进行中
  4. UPDATED_BY_ID - 拥有 更新记录

  5. UPDATED_TIMESTAMP - 此记录何时更新。
  6. TASK_ID - 状态正在改变的任务

现在一整天,一条记录可以移动到不同的状态。

我正在寻找一个查询来给出如下回复:

╔═════════════════╤══════╤════════════╤═══════╗
║ Hour_of_the_day │ OPEN │ INPROGRESS │ CLOSE ║
╠═════════════════╪══════╪════════════╪═══════╣
║ 1               │ 10   │ 0          │ 0     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 2               │ 10   │ 0          │ 0     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 3               │ 10   │ 0          │ 0     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 4               │ 9    │ 1          │ 0     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 5               │ 9    │ 1          │ 0     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 6               │ 8    │ 2          │ 0     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 7               │ 8    │ 2          │ 0     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 8               │ 8    │ 1          │ 1     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 9               │ 8    │ 0          │ 2     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 10              │ 6    │ 2          │ 2     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 11              │ 6    │ 1          │ 3     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 12              │ 5    │ 2          │ 3     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 13              │ 4    │ 3          │ 3     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 14              │ 4    │ 3          │ 3     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 15              │ 2    │ 3          │ 5     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 16              │ 1    │ 2          │ 7     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 17              │ 0    │ 1          │ 9     ║
╟─────────────────┼──────┼────────────┼───────╢
║ 18              │ 0    │ 0          │ 10    ║
╟─────────────────┼──────┼────────────┼───────╢
║ 19              │ 0    │ 0          │ 10    ║
╟─────────────────┼──────┼────────────┼───────╢
║ 20              │ 0    │ 0          │ 10    ║
╟─────────────────┼──────┼────────────┼───────╢
║ 21              │ 0    │ 0          │ 10    ║
╟─────────────────┼──────┼────────────┼───────╢
║ 22              │ 0    │ 0          │ 10    ║
╟─────────────────┼──────┼────────────┼───────╢
║ 23              │ 0    │ 0          │ 10    ║
╟─────────────────┼──────┼────────────┼───────╢
║ 24              │ 0    │ 0          │ 10    ║
╚═════════════════╧══════╧════════════╧═══════╝

注意:假设一项任务已被标记为 OPEN,并且与过去 5 小时相比状态没有变化,则必须计算所有 5 小时。关闭和进行中等其他状态也是如此,因为并非所有条目每小时都会更改。

基本上每小时有多少张票是打开的、关闭的或正在进行中的。

我不确定如何为此逻辑编写查询。但下面是我的尝试,它给出了完全不同的输出。

 SELECT TO_CHAR(t.UPDATED_TIMESTAMP , 'HH24') AS hour,
         COUNT(*) AS numPerHour, t.STATUS
    FROM STATUS_HISTORY t
    WHERE t.UPDATED_TIMESTAMP  >= to_date('29-OCT-18','DD-MON-YY')
    AND t.UPDATED_TIMESTAMP     < to_date('30-OCT-18','DD-MON-YY')
GROUP BY TO_CHAR(t.UPDATED_TIMESTAMP , 'HH24'), t.STATUS;

╔═════════════════╤════════════╤════════════╗
║ Hour_of_the_day │ NumPerHour │ INPROGRESS ║
╠═════════════════╪════════════╪════════════╣
║ 06              │ 2          │ OPEN       ║
╟─────────────────┼────────────┼────────────╢
║ 09              │ 5          │ OPEN       ║
╟─────────────────┼────────────┼────────────╢
║ 09              │ 2          │ OPEN       ║
╟─────────────────┼────────────┼────────────╢
║ 09              │ 3          │ CLOSE      ║
╟─────────────────┼────────────┼────────────╢
║ 07              │ 1          │ INPROGRESS ║
╟─────────────────┼────────────┼────────────╢
║ 08              │ 8          │ OPEN       ║
╟─────────────────┼────────────┼────────────╢
║ 11              │ 1          │ CLOSE      ║
╟─────────────────┼────────────┼────────────╢
║ 08              │ 1          │ INPROGRESS ║
╟─────────────────┼────────────┼────────────╢
║ 07              │ 3          │ OPEN       ║
╟─────────────────┼────────────┼────────────╢
║ 11              │ 2          │ CLOSE      ║
╟─────────────────┼────────────┼────────────╢
║ 12              │ 1          │ INPROGRESS ║
╚═════════════════╧════════════╧════════════╝

我想了解是否有另一种方法可以通过 java 程序来处理它,或者查询可以提供这个结果。

【问题讨论】:

  • 关闭的任务何时不再感兴趣?如果这一天的任务根本没有活动怎么办 - 过去一段时间内是否有未完成的任务? status_history 是一张大表吗,您能否在查询运行时锁定或乐意获得近似数字(未锁定它的结果)。您打算在白天还是在一天结束时运行此查询或其他一些频率?
  • TASK_ID 包含一天中所有任务的任务,因此最初所有任务在一天开始时都是打开的。它不是一张很大的桌子。
  • 白天不打开任务?
  • 不,我们不是每天都打开它。

标签: java mysql oracle


【解决方案1】:

使用条件聚合。

select COUNT( CASE WHEN STATUS = 'OPEN' THEN 1 END ) as OPEN,
       COUNT( CASE WHEN STATUS = 'INPROGRESS' THEN 1 END ) as INPROGRESS,
       COUNT( CASE WHEN STATUS = 'CLOSE' THEN 1 END ) as CLOSE
      ....
      ....
 GROUP BY TO_CHAR(t.UPDATED_TIMESTAMP , 'HH24') --remove t.STATUS

【讨论】:

  • 这仅给出在哪个小时内发生变化的结果。但是假设没有任何变化,我们希望拥有与前一小时相同的状态。例如在第 1 小时,状态为 1-打开、1-关闭、0-进行中。现在第 2 小时没有变化,状态仍然保持不变。但它无法通过您提到的查询获得。
  • @Ashu :编辑您的问题并为STATUS_HISTORY 添加示例行,以获得您期望的结果。 dbfiddle 模拟会更有帮助。
【解决方案2】:

你可以用 CASE 做到这一点:

SELECT TO_CHAR(t.UPDATED_TIMESTAMP , 'HH24') AS hour,
         COUNT(*) AS numPerHour, sum(case when t.STATUS='OPEN' then 1 ELSE 0 END) AS OPEN,
         sum(case when t.STATUS='CLOSE' then 1 ELSE 0 END) AS CLOSE,
         sum(case when t.STATUS='INPROGRESS' then 1 ELSE 0 END) AS INPROGRESS

    FROM STATUS_HISTORY t
    WHERE t.UPDATED_TIMESTAMP  >= to_date('29-OCT-18','DD-MON-YY')
    AND t.UPDATED_TIMESTAMP     < to_date('30-OCT-18','DD-MON-YY')
GROUP BY TO_CHAR(t.UPDATED_TIMESTAMP , 'HH24'), t.STATUS

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多