连续多天过去的午夜查询

时间:2018-10-16 03:30:45

标签: sql-server tsql

这是我的问题。

在第一个班次下,查询运行正常且繁琐。但是对于第二个班次,我必须分两个部分进行,因为时间已经超过了午夜。

我想在一个查询中运行第二个班次,因为我必须将所有数据粘贴到电子表格中,但是要粘贴两次以进行第二个班次然后进行排序。我尝试了多种解决方案,但是没有结果或错误

请注意,我应要求一次做一周,而不是每个星期从同一天开始,或者可能不是几天,或者有时是整个月。这三者都将在我输入的日期范围内按需工作,但是如果我能以某种方式针对第二个班次在一个查询中运行,那将是很好的。第二班时间为下午5点至凌晨4点或军事时间1700至0400。

谢谢!

   SELECT TOP (100000) 
   [line_ID]
  ,[VIN]
  ,[sequence]
  ,[load_time]

----------------First Shift-------------------------------

 FROM [NYSUS_SEQUENCE_MES].[dbo].[broadcasts_in]
 WHERE line_ID = 100 and  load_time > '10/08/2018' AND load_time <= D 
 ATEADD(day,1,'10/14/2018') 
 AND DATEPART(hour,load_time) >= 5 AND DATEPART(hour,load_time) <= 16
 order by load_time


-------------Second Shift----------------------------------

-------------NEED TO RUN THE TIME PARTS INDEPENDANTLY------
SELECT TOP (100000) 
   [line_ID]
  ,[VIN]
  ,[sequence]
  ,[load_time]


FROM [NYSUS_SEQUENCE_MES].[dbo].[broadcasts_in]
WHERE line_ID = 100 and  load_time > '10/08/2018' AND load_time <= 
DATEADD(day,1,'10/14/2018') 
AND DATEPART(hour,load_time) >= 17 AND DATEPART(hour,load_time) <= 2359
order by load_time


SELECT TOP (100000) 
   [line_ID]
  ,[VIN]
  ,[sequence]
  ,[load_time]

FROM [NYSUS_SEQUENCE_MES].[dbo].[broadcasts_in]
WHERE line_ID = 100 and  load_time > '10/08/2018' AND load_time <= 
DATEADD(day,1,'10/14/2018') 
AND DATEPART(hh,load_time) >= 0 AND DATEPART(hh,load_time) <= 4
order by load_time

3 个答案:

答案 0 :(得分:1)

如果查询返回正确的结果,则 easy-cheesy 方法为UNION ALL

SELECT t.*
FROM
(
        SELECT TOP (100000)
           'Query 1' AS Querymarker
          ,[line_ID]
          ,[VIN]
          ,[sequence]
          ,[load_time]

        FROM [NYSUS_SEQUENCE_MES].[dbo].[broadcasts_in]
        WHERE line_ID = 100 and  load_time > '10/08/2018' AND load_time <= 
        DATEADD(day,1,'10/14/2018') 
        AND DATEPART(hour,load_time) >= 17 AND DATEPART(hour,load_time) <= 2359

        UNION ALL    

        SELECT TOP (100000) 
           'Query 2' AS Querymarker
          ,[line_ID]
          ,[VIN]
          ,[sequence]
          ,[load_time]

        FROM [NYSUS_SEQUENCE_MES].[dbo].[broadcasts_in]
        WHERE line_ID = 100 and  load_time > '10/08/2018' AND load_time <= 
        DATEADD(day,1,'10/14/2018') 
        AND DATEPART(hh,load_time) >= 0 AND DATEPART(hh,load_time) <= 4
    ) t
    order by t.load_time;

提示1

我添加了一个Querymarker列,您可以查看该查询返回了一行,但是-大概-不需要,您可以将其删除...

提示2

您应避免使用与文化相关的日期格式。 10/08/2018可以是8月10日或10月8日,具体取决于计算机的设置。尝试使用独立的设置,在您的情况下,我倾向于不分隔 '20181008'(带引号,无论如何在10月8日)。

答案 1 :(得分:0)

下面的方法将动态生成一组代表2 x 12小时班次的行,以覆盖日期范围:

declare @start as datetime = '20180901 00:00:00'
declare @finish as datetime = '20181001 00:00:00'

;WITH digits AS (
      SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL
      SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
      )
, tally AS (
      SELECT 
              d1s.n 
            + d10s.n * 10
            --+ d100s.n * 100  /* add more like this as needed */
            --+ d1000s.n * 1000  /* add more like this as needed */
            AS n
      FROM digits d1s
      CROSS JOIN digits d10s
      --CROSS JOIN digits d100s /* add more like this as needed */
      --CROSS JOIN digits d1000s /* add more like this as needed */
      )
, range as (
    select
         n
       , dateadd(hour,5,dateadd(day,n-1,@start))  shift1_start
       , dateadd(hour,17,dateadd(day,n-1,@start)) shift2_start
       , dateadd(hour,29,dateadd(day,n-1,@start)) next_shift1_start
    from tally
    where dateadd(day,n-1,@start) <= @finish
    )
select t.*
from range
inner join [NYSUS_SEQUENCE_MES].[dbo].[broadcasts_in] AS t 
    ON t.load_time >= range.shift2_start and t.load_time < next_shift1_start
order by t.load_time

请参见此处演示的内容:https://rextester.com/ODUNU15588

nb:如果需要更多行,请遵循所示的交叉连接和计算的相同模式。另外,如果您已经有一个数字表或日历表,则可以改用它。生成的换挡边界看起来像这样(dd.mm.yyyy):

       n       shift1_start          shift2_start        next_shift1_start      
 ---- ---- --------------------- --------------------- --------------------- 
   1    0   31.08.2018 05:00:00   31.08.2018 17:00:00   01.09.2018 05:00:00  
   2    1   01.09.2018 05:00:00   01.09.2018 17:00:00   02.09.2018 05:00:00  
...
  31   30   30.09.2018 05:00:00   30.09.2018 17:00:00   01.10.2018 05:00:00  
  32   31   01.10.2018 05:00:00   01.10.2018 17:00:00   02.10.2018 05:00:00 

使用这种方法解决问题,可以选择单个查询中单个班次的数据,也可以通过单个查询中的两个班次区分数据。

答案 2 :(得分:0)

您需要的是在OR中包含一个where clause,以包括两个允许的小时数:

select
*
from [NYSUS_SEQUENCE_MES].[dbo].[broadcasts_in]
WHERE load_time > '10/08/2018' 
AND load_time <=  DATEADD(day,1,'10/14/2018') 
AND ((DATEPART(hour,load_time) >= 0 AND DATEPART(hh,load_time) <= 4)
   OR
     (DATEPART(hour,load_time) >= 17 AND DATEPART(hour,load_time) <= 23)
     )
order by load_time
;

另请参阅:https://rextester.com/SUM30585