分类间隔日夜SQL服务器

时间:2015-11-17 08:51:13

标签: sql sql-server

我有一个时间框架:

FROMTIME:06:01:00 - TOTIME:23:59:00   = DAY
FROMTIME:23:59:01 - TOTIME:06:00:00   = Night

我有一辆车的TIME_IN和TIME_OUT。 如何通过汽车分类间隔时间是DAY或Night或DayAndNight 。我使用代码但执行时间很长:

Declare @From_Time_Day time
		,@To_Time_Day time
		,@From_Time_Night time
		,@To_Time_Night time
		,@Midnight time
		
set @From_Time_Day = (select FROM_TIME from DAY_STATUS where DAY_CHECK=1)
set @To_Time_Day = (select TO_TIME from DAY_STATUS where DAY_CHECK=1)
set @From_Time_Night = (select FROM_TIME from DAY_STATUS where DAY_CHECK=2)
set @To_Time_Night = (select TO_TIME from DAY_STATUS where DAY_CHECK=2)
set @Midnight = '00:00:00'

select * from (
select 
	(case when ( 
				cast((select top 1 IO_TIME from IO_INFO where IO_STATUS= 'IN' and CA_ID = Data.CA_ID and IO_ID < Data.IO_ID order by IO_ID desc) as date)
				= cast(Data.IO_TIME as date)
				)
		  then 
				(
				case when (
						   cast((select top 1 IO_TIME from IO_INFO where IO_STATUS= 'IN' and CA_ID = Data.CA_ID and IO_ID < Data.IO_ID order by IO_ID desc) as time) >= @From_Time_Day
						   and cast(Data.IO_TIME as time) <=@To_Time_Day
				          ) then 'DAY'    
				     when (
				           cast((select top 1 IO_TIME from IO_INFO where IO_STATUS= 'IN' and CA_ID = Data.CA_ID and IO_ID < Data.IO_ID order by IO_ID desc) as time) >= @From_Time_Night
				           and cast(Data.IO_TIME as time) < @Midnight
						  ) then 'Night'
					 when (
					       cast((select top 1 IO_TIME from IO_INFO where IO_STATUS= 'IN' and CA_ID = Data.CA_ID and IO_ID < Data.IO_ID order by IO_ID desc) as time) >= @Midnight
						   and cast(Data.IO_TIME as time) <= @To_Time_Night
					      ) then 'Night'   
					else 'DayAndNight' end
				) 
		  when  (
				cast((select top 1 IO_TIME from IO_INFO where IO_STATUS= 'IN' and CA_ID = Data.CA_ID and IO_ID < Data.IO_ID order by IO_ID desc) as date)
				<> cast(Data.IO_TIME as date)
				)
		  then	(
				case when(
						 (cast((select top 1 IO_TIME from IO_INFO where IO_STATUS= 'IN' and CA_ID = Data.CA_ID and IO_ID < Data.IO_ID order by IO_ID desc) as time) >= @From_Time_Night and 
						 cast((select top 1 IO_TIME from IO_INFO where IO_STATUS= 'IN' and CA_ID = Data.CA_ID and IO_ID < Data.IO_ID order by IO_ID desc) as time) < @Midnight)
						 and (cast(Data.IO_TIME as time)>=@Midnight and cast(Data.IO_TIME as time)<=@To_Time_Night)
				         ) then 'Night'
				    else 'DayAndNight' end
		        ) 
		 end
) as INTERVAL 
from IO_INFO as Data where IO_STATUS = 'OUT'

1 个答案:

答案 0 :(得分:0)

好的,看到这是一个Tricky类型的查询我已经失去了一些时间来找到解决方案,我已经在一个包含4个字段,ID,Car,TimeOut,TimeIn的测试数据库中创建了一个表,我已在此表格中插入了一些行以获取样本,然后我创建了一个查询,该查询返回我的汽车每次旅行的时段状态。

以下是查询:

SELECT [ID]
  ,[Car]
  ,[TimeOut]
  ,[TimeIn]
  , MultiDay
  ,OutDAyNight
  ,InDAyNight
  , CASE WHEN Multiday = 1 THEN 'Day/Night'
        WHEN OutDAyNight+InDAyNight = 1 THEN 'Day/Night'
        WHEN OutDAyNight+InDAyNight = 2 THEN 'Day'
        WHEN OutDAyNight+InDAyNight = 0 THEN 'Night' END AS    Periods 
FROM 
(SELECT [ID]
          ,[Car]
          ,[TimeOut]
          ,[TimeIn]       
          , CASE WHEN DATEDIFF(hour, [TimeOut],[TimeIn]) > 18 
                 THEN 1 ELSE 0 END AS MultiDay    
          , CASE WHEN DATEPART(hour, [TimeOut]) > 6 AND 
               DATEPART(hour, [TimeOut]) <=23 THEN 1
               WHEN DATEPART(hour, [TimeOut]) = 6 AND 
               DATEPART(minute, [TimeOut]) > 0 THEN 1
               ELSE 0 END AS OutDAyNight      
          , CASE WHEN DATEPART(hour, [TimeIn]) > 6 AND 
               DATEPART(hour, [TimeIn]) <=23 THEN 1
               WHEN DATEPART(hour, [TimeIn]) = 6 AND 
               DATEPART(minute, [TimeIn]) > 0 THEN 1        
               ELSE 0 END AS InDAyNight       
          FROM [dbo].[TbCarInOut] ) Times

使用这个双重查询,在第一个选择中(脚本中的较低的一个)我使用Datediff函数来查看退出和返回汽车之间的时间是否超过18小时,这肯定意味着有一天和夜晚。然后我使用Datepart函数来了解输出时间是Night还是Day设置为0表示夜晚和1表示日期,我也是这样做的时间In,这样,在第二个查询中,我可以使用一个简单的情况和确定期间是白天/白天,白天还是夜晚的总和。 HTH