我有一个奇怪的逻辑问题,我似乎无法解决这个问题(也许是因为研究太久了)。
在我工作的地方,我们有一个非常古老的软件,我们需要使用它来跟踪我们使用的设备的状态。该软件提供非常少的功能来操纵这些状态,以尝试并提供对停机时间的良好分析。我一直在使用Access中的数据库应用程序(因为它是他们提供给我的唯一工具),可以将旧系统中的状态数据导入到更容易操作的格式中。
状态数据从旧程序中吐出的方式非常简单:
EQUIPNAME STATUS STARTDATETIME ENDDATETIME
读取该文本并将其插入Access中的表格非常容易。我遇到的问题来自于试图找出一件设备在不同日期范围内在不同状态下花费了多少小时。
开始/结束日期/时间可以是任何时间长度。查找包含日期的行很困难。我一直在SQL中使用BETWEEN语句试图找到它们,这些语句在很大程度上运作得很好:
SELECT * FROM Statuses WHERE
(StartDateTime BETWEEN [StartDT] AND [EndDT])
OR
(EndDateTime BETWEEN [StartDT] AND [EndDT])
真正的问题是,StartDateTime是在StartDT之前,而EndDateTime是在EndDT之后(即我正在寻找的整个范围是INSIDE此状态的开始/结束日期)。它根本找不到它,这是有道理的。
我似乎无法想出一个优雅的解决方案。我需要能够选择包含状态的所有行,这些行包含或包含在提供的日期范围内。我通常不会来这里遇到这么简单的问题,但是我的大脑和Google-fu都让我失望了。
一些示例数据:
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
答案 0 :(得分: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
以上是航空代码,但显示了首先获取重叠记录所需的基本处理循环,然后显示处理循环,以便为日期范围内的每条记录添加日期/时间,该日期/时间与给定日期范围相符
答案 1 :(得分:0)
有趣的问题!抱歉没有太多时间来进行复杂化,但我建议探索Partition
函数,或者/和/或以日期作为列标题进行交叉表查询。有关msoffice site和here的更多信息。