SQL获取两次之间的值

时间:2018-12-12 13:28:14

标签: sql sql-server tsql sql-server-2012

我在SQL Server(2012)中有一张表, 它包含以下内容:(样本数据)

<table><tbody><tr><th>itemRef(vchar50)</th><th>itemStatus(vchar50)</th><th>statusStart(datetime)</th><th>statusFinish(datetime)</th></tr><tr><td>itemXYZ</td><td>ORDER RECEIVED</td><td>2018-12-10 20:10:18.000</td><td>2018-12-10 22:10:19.000</td></tr><tr style='background-color: #cecece;'><td>itemXYZ</td><td>PICKING</td><td>2018-12-10 22:10:19.000</td><td>2018-12-11 11:14:32.000</td></tr><tr><td>itemXYZ</td><td>PACKING</td><td>2018-12-11 11:14:32.000</td><td>2018-12-11 12:10:53.000</td></tr><tr><td>itemXYZ</td><td>DISPATCH NOTICE</td><td>2018-12-11 12:10:53.000</td><td>2018-12-11 12:10:57.000</td></tr><tr><td>itemXYZ</td><td>AWAITING DISPATCH</td><td>2018-12-11 12:10:57.000</td><td>2018-12-11 12:27:14.000</td></tr></tbody></table>

我正在尝试对将一周中的几天转换为轮班的表运行查询:

  • (日班:星期一-星期四8am-10pm和星期五8am-3.30pm)

    ((DATEPART(dw, statusStart) in (2,3,4,5) and CONVERT(TIME, statusStart)>=''08:00:00'' AND CONVERT(TIME, statusStart) < ''22:00:00'') OR 
    (DATEPART(dw, statusStart) in (5) and CONVERT(TIME, statusStart) >=''08:00:00'' AND CONVERT(TIME,statusStart) < ''15:30:00''))';
    
  • (夜班:星期一-星期五10pm-8am)

    ((DATEPART(dw, statusStart) in (2,3,4,5) and (CONVERT(TIME, statusStart) >=''22:00:00'' OR CONVERT(TIME, statusStart) < ''08:00:00'')))';
    
  • (周末班:周五-周一3.30pm-8am)

    ((DATEPART(dw, statusStart) in (6,1) OR (DATEPART(dw, statusStart) in (5) and CONVERT(TIME, statusStart) >=''15:30:00'') OR (DATEPART(dw, statusStart) in (2) and CONVERT(TIME, statusStart) <''08:00:00'')))';
    

以上内容是存储过程的一部分-该存储过程可以正确返回数据,除非itemStatus在转换开始之前以及在转换期间结束之前已开始-上表中突出显示的行!

如果我运行查询-从表中选择*为轮班制-采摘状态将被排除,因为它是在轮班制开始之前开始的-上午8点

image1 1

我要实现的目标是,如果我运行查询,请从表中选择*,其中shift是Day shift

image2 2

上午8点成为新的拣选开始时间- 然后,我可以查询-statusStart和statusFinish之间的时间差是多少,其中班次是Day shift,而itemStatus是'Picking'

我希望这有道理!

1 个答案:

答案 0 :(得分:0)

这样的事情可能会让您朝着想要的方向走...

SELECT 
    itemRef,
    itemStatus,
    CASE WHEN CONVERT(TIME, statusStart) >  CASE WHEN DATEPART(dw, statusStart)  = 5 THEN '15:30:00' ELSE '22:00:00' END THEN DATEADD(dd, 0, DATEDIFF(dd, 0, statusFinish)) + CAST('08:00:00' AS DATETIME) ELSE statusStart END AS statusStart,
    statusFinish
FROM #test
WHERE 
   (DATEPART(dw, statusStart) in (2,3,4,5) and CONVERT(TIME, statusStart)>='08:00:00' AND CONVERT(TIME, statusStart) < CASE WHEN DATEPART(dw, statusStart)  = 5 THEN '15:30:00' ELSE '22:00:00' END)
   OR (DATEPART(dw, statusFinish) in (2,3,4,5) and CONVERT(TIME, statusFinish)>='08:00:00' AND CONVERT(TIME, statusFinish) < CASE WHEN DATEPART(dw, statusStart)  = 5 THEN '15:30:00' ELSE '22:00:00' END)

您可以在这里进行测试:Android in-app billing Verification of Receipt in Dot Net(C#)

返回以下结果:

https://rextester.com/TGO17469

更新 根据评论过滤“选择”,需要对WHERE子句进行少量调整:

WHERE 
   (
       (DATEPART(dw, statusStart) in (2,3,4,5) and CONVERT(TIME, statusStart)>='08:00:00' AND CONVERT(TIME, statusStart) < CASE WHEN DATEPART(dw, statusStart)  = 5 THEN '15:30:00' ELSE '22:00:00' END)
       OR (DATEPART(dw, statusFinish) in (2,3,4,5) and CONVERT(TIME, statusFinish)>='08:00:00' AND CONVERT(TIME, statusFinish) < CASE WHEN DATEPART(dw, statusStart)  = 5 THEN '15:30:00' ELSE '22:00:00' END)
   )
AND itemStatus = 'Picking'

可在此处测试:enter image description here