SQL从两个时间字段中选择小时但在一个范围之间

时间:2017-12-06 08:25:58

标签: sql sql-server tsql time type-conversion

我正在使用SQL Server 2014,在此之前我已经尝试了几件事。

我需要完成的是: 我有一个存储两个时间列的表,其中包含值,例如9:00或2:34等等。

我需要计算每天的工作时间和工作时间。 每日营业时间必须从8:00到20:00,晚上的时间从20:00到8:00

如果我有两个时间字段,则可以将值设为

4:00和12:00

12:00和20:00

22:00和6:00

我想要做的是检索两个对应于每日小时和夜晚的十进制值,也许有一个SQL函数,我不知道哪个传递了两个值,一个范围为我执行此任务,或者可能这是我自己建立一个

的情况

1 个答案:

答案 0 :(得分:0)

我认为你可以使用辅助表

CREATE TABLE HourInfo(
  h time NOT NULL,
  isNight bit NOT NULL
CONSTRAINT PK_HourInfo PRIMARY KEY(h)
)
GO

INSERT HourInfo(h,isNight)VALUES
('00:00',1),('01:00',1),('02:00',1),('03:00',1),('04:00',1),('05:00',1),('06:00',1),('07:00',1),('08:00',1),
('09:00',0),('10:00',0),('11:00',0),('12:00',0),('13:00',0),('14:00',0),('15:00',0),('16:00',0),('17:00',0),('18:00',0),('19:00',0),
('20:00',1),('21:00',1),('22:00',1),('23:00',1)
GO

CREATE TABLE MinuteInfo(
  m time NOT NULL,
  isNight bit NOT NULL
CONSTRAINT PK_MinuteInfo PRIMARY KEY(m)
)
GO

INSERT MinuteInfo(m,isNight)
SELECT DATEADD(MINUTE,m.m,h.h) m,h.isNight
FROM HourInfo h
CROSS JOIN
  (
    SELECT i*10+j AS m
    FROM (VALUES(0),(1),(2),(3),(4),(5)) n1(i)
    CROSS JOIN (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) n2(j)
  ) m
GO

并使用以下查询

SELECT CAST('04:00' AS time) t1,CAST('12:00' AS time) t2 INTO #TestData
UNION ALL
SELECT CAST('12:00' AS time) t1,CAST('20:00' AS time) t2
UNION ALL
SELECT CAST('22:00' AS time) t1,CAST('06:00' AS time) t2
UNION ALL
SELECT CAST('00:00' AS time) t1,CAST('05:15' AS time) t2

/*
SELECT
  d.t1,
  d.t2,
  COUNT(CASE WHEN h.isNight=1 THEN 1 END) [night hours],
  COUNT(CASE WHEN h.isNight=0 THEN 1 END) [daily hours]
FROM #TestData d
JOIN HourInfo h
ON
     (d.t1>d.t2 AND ((h.h>=d.t1 AND h.h<=CAST('23:00' AS time)) OR (h.h>=CAST('00:00' AS time) AND h.h<d.t2)))
  OR (d.t1<=d.t2 AND h.h>=d.t1 AND h.h<=d.t2)
GROUP BY d.t1,d.t2
*/

SELECT
  d.t1,
  d.t2,
  COUNT(CASE WHEN m.isNight=1 THEN 1 END)/60. [night hours],
  COUNT(CASE WHEN m.isNight=0 THEN 1 END)/60. [daily hours]
FROM #TestData d
JOIN MinuteInfo m
ON
     (d.t1>d.t2 AND ((m.m>=d.t1 AND m.m<=CAST('23:59' AS time)) OR (m.m>=CAST('00:00' AS time) AND m.m<d.t2)))
  OR (d.t1<=d.t2 AND m.m>=d.t1 AND m.m<d.t2)
GROUP BY d.t1,d.t2

DROP TABLE #TestData