1

我有一个奇怪的逻辑问题,我似乎无法解决(也许是因为研究太久了)。

在我工作的地方,我们有一个非常古老的软件,我们需要使用它来跟踪我们使用的设备的状态。该软件提供很少的功能来操纵这些状态以尝试提供对停机时间的良好分析。我一直在使用 Access 中的数据库应用程序(因为它是他们提供给我的唯一工具),以将旧系统中的状态数据导入更易于操作的格式。

从旧程序中吐出状态数据的方式相当简单:

设备名称 状态 开始日期时间 结束日期时间

阅读该文本并将其插入 Access 中的表中很容易。我遇到的问题来自于试图找出一台设备在不同日期范围内处于不同状态的时间。

开始/结束日期/时间可以是任何时间长度。查找哪些行包含日期很困难。我一直在 SQL 中使用 BETWEEN 语句来尝试找到它们,它们在大多数情况下效果很好:

SELECT * FROM Statuses WHERE 
    (StartDateTime BETWEEN [StartDT] AND [EndDT]) 
OR 
    (EndDateTime BETWEEN [StartDT] AND [EndDT])

真正的问题是当 StartDateTime 在 StartDT 之前而 EndDateTime 在 EndDT 之后(即我正在寻找的整个范围都在这个状态的开始/结束日期之内)。它根本找不到它,这是有道理的。

我似乎无法想出一个优雅的解决方案。我需要能够选择包含包含或包含在提供的日期范围内的状态的所有行。我通常不会为了这么简单的问题来这里,但我的大脑和谷歌让我失望了。

一点样本数据:

EQUIP STATUS STARTDATETIME    ENDDATETIME
A123  OPER   01/30/2013 21:30 12/31/1999 00:00
A123  DFM    01/26/2013 10:42 01/30/2013 21:29
A123  OPER   01/01/2013 00:00 01/26/2013 10:41
B123  OPER   01/01/2013 00:00 12/31/1999 00:00
C123  DFU    01/29/2013 12:31 12/31/1999 00:00
C123  OPER   01/01/2013 00:00 01/29/2013 12:30
4

2 回答 2

2

在以下情况下会发生任何类型的预订勾结:

RequestStartDate <= EndDate 
and 
RequestEndDate >= StartDate 

以上也将返回重叠。因此,如果我查询今天 + 明天,并且范围从年初到年底,则查询将包含在该范围内。

例如:

 Select * from tblEQUIP 
 where 
   #01/31/2013# <= ENDDATETIME
   and
   #02/01/2013# >= StartDateTime

此时您可以“处理”每条记录。您可能必须使用类似的东西:

Do while RecordDate.eof = false

   For datePtr = RequestStartDateTime to RequestendDateTime
      If datePtr >= RecordData!StartDateTime and DatePtr <= RecordData!EndDateTime then
         DaysTotal = DaysTotal  + 1
      End if
   Next DatePtr
   recordData.Movenext
loop

以上是航空代码,但显示了您首先需要获取重叠记录的基本处理循环,然后是一个处理循环,用于为您的日期范围内的每个记录添加天数/时间,这些记录确实属于给定的日期范围。

于 2013-01-31T17:09:25.573 回答
0

有趣的问题!很抱歉现在没有太多时间来阐述,但我建议为此探索该Partition功能,或和/或使用日期作为列标题进行交叉表查询。有关msoffice 网站此处的更多信息。

于 2013-01-31T16:20:01.457 回答