[英]SQL query to retrieve records that fall outside of a time range defined between two datetime fields
我正在尝试在我们的工作单系统中查找异常情况,其中我的一个where语句需要检索最近30天内超出certian时间范围的工作发生的记录。 我正在尝试确定是否在上午6点之前或下午4点之后进行了任何工作。 我的数据库有一个datetime字段,用于存储此信息。
到目前为止,我有这个查询:
Select WORKORDERID, DESCRIPTION, actualstartdate, actualfinishdate
FROM [CityWorks].[AZTECA].[WORKORDER]
WHERE actualstartdate BETWEEN '2014-05-05 01:00:00.000' AND '2014-06-05 23:00:00.000'
order by actualstartdate desc
我该如何添加where语句,以查看Actualstartdate列中的工作是否发生在realyfinishdate中的“ yyyy-mm-dd 06:00:00.000”之前或“ yyyy-mm-dd 16:00:00.000”之后,同时仍从最近30天?
快速解决方案:选择所有行并减去非可疑行
演示: http : //sqlfiddle.com/#!3/f0651/1
Select WORKORDERID, DESCRIPTION, actualstartdate, actualfinishdate
FROM [CityWorks].[AZTECA].[WORKORDER]
WHERE actualstartdate BETWEEN '2014-05-05 01:00:00.000' AND '2014-06-05 23:00:00.000'
EXCEPT
Select WORKORDERID, DESCRIPTION, actualstartdate, actualfinishdate
FROM [CityWorks].[AZTECA].[WORKORDER]
WHERE actualstartdate BETWEEN '2014-05-05 01:00:00.000' AND '2014-06-05 23:00:00.000'
AND actualstartdate >= DATEADD(hour, 6,CAST(CAST(actualstartdate AS date) AS datetime))
AND actualfinishdate <= DATEADD(hour,16,CAST(CAST(actualfinishdate AS date) AS datetime))
AND CAST(actualstartdate AS date) = CAST(actualfinishdate AS date)
MS SQL Server 2008架构设置 :
CREATE TABLE WORKORDER
([WORKORDERID] int, [DESCRIPTION] varchar(3), [actualstartdate] datetime, [actualfinishdate] datetime)
;
INSERT INTO WORKORDER
([WORKORDERID], [DESCRIPTION], [actualstartdate], [actualfinishdate])
VALUES
(1, 'w1', '2014-05-07 01:00:00', '2014-05-07 05:00:00'),
(2, 'w2', '2014-05-07 04:00:00', '2014-05-07 12:00:00'),
(3, 'w3', '2014-05-07 05:59:00', '2014-05-07 12:00:00'),
(4, 'w4', '2014-05-07 06:00:00', '2014-05-07 12:00:00'),
(5, 'w5', '2014-05-07 06:01:00', '2014-05-07 16:00:00'),
(6, 'w6', '2014-05-07 06:01:00', '2014-05-07 16:01:00'),
(7, 'w7', '2014-05-07 06:01:00', '2014-05-08 12:01:00')
;
查询1 :
Select WORKORDERID, DESCRIPTION, actualstartdate, actualfinishdate
FROM [WORKORDER]
WHERE actualstartdate BETWEEN '2014-05-05 01:00:00.000' AND '2014-06-05 23:00:00.000'
and (CAST(actualstartdate AS date) = CAST(actualfinishdate AS date)
and (((DATEPART(hh, actualstartdate)*3600)+
(DATEPART(mi, actualstartdate)*60)+
DATEPART(ss, actualstartdate)) < 21600 or
((DATEPART(hh, actualfinishdate)*3600)+
(DATEPART(mi, actualfinishdate)*60)+
DATEPART(ss, actualfinishdate)) > 57600) or
CAST(actualstartdate AS date) <> CAST(actualfinishdate AS date))
order by actualstartdate desc
结果 :
| WORKORDERID | DESCRIPTION | ACTUALSTARTDATE | ACTUALFINISHDATE |
|-------------|-------------|----------------------------|----------------------------|
| 6 | w6 | May, 07 2014 06:01:00+0000 | May, 07 2014 16:01:00+0000 |
| 7 | w7 | May, 07 2014 06:01:00+0000 | May, 08 2014 12:01:00+0000 |
| 3 | w3 | May, 07 2014 05:59:00+0000 | May, 07 2014 12:00:00+0000 |
| 2 | w2 | May, 07 2014 04:00:00+0000 | May, 07 2014 12:00:00+0000 |
| 1 | w1 | May, 07 2014 01:00:00+0000 | May, 07 2014 05:00:00+0000 |
您可以使用datepart函数查看小时:
SELECT WORKORDERID ,
DESCRIPTION ,
actualstartdate ,
actualfinishdate
FROM [CityWorks].[AZTECA].[WORKORDER]
WHERE actualstartdate BETWEEN '2014-05-05 01:00:00.000'
AND '2014-06-05 23:00:00.000'
AND (DATEPART(HOUR, actualstartdate) <= 6
OR DATEPART(HOUR, actualstartdate) => 16)
ORDER BY actualstartdate DESC
您可以轻松获取日期的小时部分,如下所示:
DATEPART(hh, actualstartdate);
如下使用它:
Select WORKORDERID, DESCRIPTION, actualstartdate, actualfinishdate
FROM [CityWorks].[AZTECA].[WORKORDER]
WHERE actualstartdate BETWEEN '2014-05-05 01:00:00.000' AND '2014-06-05 23:00:00.000'
AND (DATEPART(hh, actualstartdate) < 6 or (DATEPART(hh, actualfinishdate) >= 16)
order by actualstartdate desc
这将获取给定日期之间的所有行,这些日期发生在早上六点之前或晚上四点之后。
编辑:如果您想允许一个确切的1600的finishfinishdate,则可以将第二个子句更改为:
or actualfinishdate > DATEADD(hh, 16, cast(actualfinishdate as date))
这将检查实际的完成日期是否在4之后。
Select WORKORDERID, DESCRIPTION, actualstartdate, actualfinishdate
FROM [CityWorks].[AZTECA].[WORKORDER]
WHERE actualstartdate BETWEEN '2014-05-05 01:00:00.000' AND '2014-06-05 23:00:00.000'
and
(CONVERT(time,actualstartdate )<'06:00' or CONVERT(time,actualfinishdate )> '16:00')
order by actualstartdate desc
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.