如何编写查询以显示日期范围中的“中断”?

时间:2015-03-06 13:28:32

标签: mysql sql

我想写一个查询来显示计算机在测试台上进行测试的日期。

然而,其中一些不止一次在测试中。例如 -

 Computer  |  Testing_Rig  | Date       | Time     | ... 
_________________________________________________________
 A         |  OnlyTestRig  | 2014-01-01 | 12:00:00 |
 A         |  OnlyTestRig  | 2014-01-02 | 12:00:00 |
 B         |  OnlyTestRig  | 2014-01-03 | 12:00:00 |
 B         |  OnlyTestRig  | 2014-01-04 | 12:00:00 |
 A         |  OnlyTestRig  | 2014-01-05 | 12:00:00 |
 A         |  OnlyTestRig  | 2014-01-06 | 12:00:00 |
 B         |  OnlyTestRig  | 2014-01-07 | 12:00:00 |
 B         |  OnlyTestRig  | 2014-01-08 | 12:00:00 |

在此(简化)数据集中,AB各自进行了两次测试。


初始查询

编写一个显示Computer开启或关闭测试日期的查询非常容易 -

SELECT 
    `Computer`,
    MIN(`Date`) AS `Date_On_Test`,
    MAX(`Date`) AS `Date_Off_Test`
FROM 
    Test_Data
WHERE 
    Testing_Rig = 'OnlyTestRig' 
GROUP BY 
    `Computer` 
ORDER BY 
    `Computer`

然而,这将产生以下结果 -

 Computer |  Date_On_Test | Date_Off_Test
__________________________________________
 A        |  2014-01-01   | 2014-01-06
 B        |  2014-01-03   | 2014-01-08 

这并未显示两台计算机都在测试装置上“交换”。


'笨拙'查询

我可以编写一个查询,每天显示每个Computer的测试时间 -

SELECT 
    `Date`,
    `Computer`,
    MIN(`Time`) AS `First_Test`,
    MAX(`Time`) AS `Last_Test`
WHERE
    `Testing_Rig` = 'OnlyTestRig'
GROUP BY 
    `Date`, 
    `Computer`
ORDER BY 
    `Date` ASC,
    `Computer` ASC

虽然这显示了测试中计算机之间的中断和交换,但这将产生一个大数据集,这对于使用来说是不切实际的,因为它将包括计算机每个测试日期的至少一个记录。

 Date       | Computer | First_Test | Last_Test
________________________________________________
 2014-01-01 | A        | 12:00:00   | 12:00:00
 2014-01-02 | A        | 12:00:00   | 12:00:00
 2014-01-03 | B        | 12:00:00   | 12:00:00 
...etc...

有没有办法可以显示'休息'并产生更有用的结果?

谢谢。

1 个答案:

答案 0 :(得分:1)

是。您可以通过在连续时将值组合在一起来完成此操作。目前还不清楚如果跳过一天会发生什么,所以我会忽略它。

您可以根据之前出现的不同的值来表征每个Computer。对于您的数据,这将导致值:

A    0
A    0
B    2
B    2
A    2
A    2
B    4
B    4

这为聚合提供了足够的信息,可以唯一标识每个组。我们可以使用相关子查询来获取此信息:

select, computer, min(date), max(date)
from (select t.*,
             (select count(*)
              from test_data t2
              where t2.date < t.date and t2.Testing_Rig = 'OnlyTestRig'
             ) as grp
      from test_data t
      where t.Testing_Rig = 'OnlyTestRig'
     ) t
group by computer, grp;