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

时间:2014-06-06 15:20:03

标签: sql sql-server

我正在尝试在我们的工作单系统中找到异常,并且我的where语句之一需要检索在过去30天内在certian时间范围内发生工作的记录。我想确定在早上6点之前或下午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' 
  order by actualstartdate desc

我将如何添加where语句,以查看在realyartdate列中的工作是否在'yyyy-mm-dd 06:00:00.000'之前或在'yyyy-mm-dd 16:00:00.000'之后的实际结束时发生从最近30天开始还是拉?

5 个答案:

答案 0 :(得分:1)

快速解决方案:选择所有行并减去非可疑行

演示: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)

答案 1 :(得分:1)

SQL Fiddle

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

<强> Results

| 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 |

答案 2 :(得分:0)

您可以使用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

答案 3 :(得分:-1)

您可以按如下方式轻松获取日期的小时部分:

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

这将获得您在给定日期之间的所有行,这些行发生在早上六点之前或四点之后。

修改 如果你想允许一个恰好16个的实际完成日期,你可以将第二个子句改为:

or actualfinishdate > DATEADD(hh, 16, cast(actualfinishdate as date)) 

这将检查实际完成日期是否在4之后。

答案 4 :(得分:-3)

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