繁体   English   中英

SQL查询以检索落在两个日期时间字段之间定义的时间范围之外的记录

[英]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)

SQL小提琴

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM