按班次分组时间戳

时间:2013-02-04 08:23:06

标签: sql tsql datetime

在我们的工厂,我们有以下转变:

  • 1:Mo - Fri:早上5点 - 下午1点
  • 2:Mo - Fri:下午1点 - 晚上9点
  • 3:Mo - Fri:晚上9点 - 凌晨5点
  • 4a:周六:早上5点 - 下午5点
  • 4b:太阳:下午5点 - 周一凌晨5点

在某个表中,我们有几个日期时间条目,我想使用查询进行分组。对于班次1,2和3,此查询正常工作::

  CASE
WHEN DATEPART(hh, c.date_time_stamp) >= 5 AND DATEPART(hh, c.date_time_stamp) < 13 THEN CONVERT(VARCHAR(10), c.date_time_stamp, 103) + ' shift 1'
WHEN DATEPART(hh, c.date_time_stamp) >= 13 AND DATEPART(hh, c.date_time_stamp) < 21 THEN CONVERT(VARCHAR(10), c.date_time_stamp, 103) + ' shift 2'
WHEN DATEPART(hh, c.date_time_stamp) >= 21 AND DATEPART(hh, c.date_time_stamp) < 24 THEN CONVERT(VARCHAR(10), c.date_time_stamp, 103) + ' shift 3'
WHEN DATEPART(hh, c.date_time_stamp) >= 00 AND DATEPART(hh, c.date_time_stamp) < 5 THEN CONVERT(VARCHAR(10), DATEADD(DAY, -1, c.date_time_stamp), 103)  + ' shift 3'  END AS shift,

这给了我某种shift_id。为了识别转移4a和4b,我可以扩展case语句,但我有点担心查询的性能。

任何人都可以给我一个提示如何创建一个以有效方式返回shift_id的函数吗?谢谢!

编辑:一些示例数据:

inventory_trans_number creation_dt             shift_id             shift_type container_code
---------------------- ----------------------- -------------------- ---------- ------------------
140952                 2013-02-04 01:03:19.043 20130203 03          3          154143591115247892
140956                 2013-02-04 01:07:20.343 20130203 03          3          154143591115247939
140962                 2013-02-04 01:10:56.417 20130203 03          3          154143591115247991
140968                 2013-02-04 01:14:55.250 20130203 03          3          154143591115248134
140970                 2013-02-04 01:17:18.883 20130203 03          3          154143591115248196
141070                 2013-02-04 02:12:59.327 20130203 03          3          154143591115248240
141076                 2013-02-04 02:16:27.480 20130203 03          3          154143591115248356
141092                 2013-02-04 02:22:44.067 20130203 03          3          154143591115248530
141096                 2013-02-04 02:25:02.157 20130203 03          3          154143591115248585
141102                 2013-02-04 02:33:51.253 20130203 03          3          154143591115248615

1 个答案:

答案 0 :(得分:1)

这会给你转变。它的工作原理是认识到这是一个数学问题,而不是数据库问题。

每周有21个班次,我们创建一个表变量来保存班次名称 - 您可能想要为此创建一个permenant表,并在Number列上添加索引。

在我们感兴趣的任何日期之前的星期一设置为5:00的时间和日期时间之间获得DATEDIFF小时,并采用此模数在24 * 7(一周的小时数)中,我们得到一个数字,表示星期一凌晨5点(即班次0)的小时数。将此值除以8即可获得班次编号。

DECLARE @FirstEverShift datetime = CONVERT(datetime, '2011-12-26 05:00')

DECLARE @ShiftTypes TABLE
(Number int NOT NULL PRIMARY KEY,
 Shift  nvarchar(2) NOT NULL)

INSERT @ShiftTypes
VALUES
(0, '1'),
(1, '2'),
(2, '3'),
(3, '1'),
(4, '2'),
(5, '3'),
(6, '1'),
(7, '2'),
(8, '3'),
(9, '1'),
(10, '2'),
(11, '3'),
(12, '1'),
(13, '2'),
(14, '3'),
(15, '4a'),
(16, 'NA'),
(17, 'NA'),
(18, '4b'),
(19, 'NA'),
(20, 'NA')

SELECT  s.date_time_stamp
        ,st.Shift
FROM    shifts s
        INNER JOIN
        @ShiftTypes st ON st.Number=DATEDIFF(HOUR, @FirstEverShift, s.date_time_stamp) % (24*7) / 8

修改

我意识到周末班次是12小时而不是8.这种方法有效但需要修改我不会做,因为我在平板电脑上!

除了除以8,除以4,这意味着表变量必须从0到40,每个8小时班次需要2个数字,每个12小时需要3个。