SQL - 查询陷入午夜的桶的时间戳

时间:2018-01-10 21:06:43

标签: sql sql-server

我的SQL体验仅限于基本查询,我所学到的一切都是通过Google-fu(主要来自本网站),通过反复试验,并且不必要,所以请原谅我的解释不清楚。

数据:表dbo。[Offload]包含每个部件[ID]的唯一标识符和部件完成时的[Timestamp]。

示例数据:

ID          TimeStamp
310963627   2018-01-10 15:30:21.000
310963562   2018-01-10 15:29:47.000
310963595   2018-01-10 15:29:04.000
310963517   2018-01-10 15:28:21.000
310963548   2018-01-10 15:27:41.000
310963469   2018-01-10 15:27:02.000
310963500   2018-01-10 15:26:17.000
310963436   2018-01-10 15:25:39.000
310963422   2018-01-10 15:24:58.000
  

修改:展开的样本数据:https://drive.google.com/open?id=1JKnL-nWGcVWNpJarZ1u-vzQqopaf51vp

我想出了一个查询,该查询将班次产生的部件数量和最后一站行的时间戳的日期分组:

位移:

Shift   1st       2nd        3rd
Start   6:30 AM   2:30 PM    10:30 PM
End     2:30 PM   10:30 PM   6:30 AM
Hours   8:00      8:00       8:00

*第3天从前一天晚上10:30开始 -ex:2018-01-10:3rd = 2018-01-09 22:30:00.0000 to 2018-01-10 06:30:00.0000

SELECT  
        [Shift],
        Count([ID]) as Assembled

FROM(
    SELECT _60.*,
        CASE WHEN (
        CONVERT(CHAR(5), Timestamp, 114) between '06:30' and '14:30'
        ) 
                THEN LEFT(CAST(TimeStamp AS DATE),10)+':1st'

             WHEN (
        CONVERT(CHAR(5), Timestamp, 114) between '14:30' and '22:30'
        ) 
                THEN LEFT(CAST(TimeStamp AS DATE),10)+':2nd'

            WHEN (
        CONVERT(CHAR(5), Timestamp, 114) between '22:30' and '24:00'
        ) 
                THEN LEFT(CAST(DATEADD(DAY, 1, TimeStamp) AS DATE),10)+':3rd' 

            WHEN (
        CONVERT(CHAR(5), Timestamp, 114) between '00:00' and '06:30'
        ) 
                THEN LEFT(CAST(DATEADD(DAY, 0, TimeStamp) AS DATE),10)+':3rd'

           END AS [Shift]
    FROM dbo.Offload _60
) _60
where TimeStamp > (DATEADD(DAY, -150, GETDATE()))

GROUP BY    [Shift]
order by CAST(LEFT([shift],10) as date) desc

目前的结果:

Shift           Assembled
2018-01-10:1st  389
2018-01-10:2nd  39
2018-01-10:3rd  406
2018-01-09:1st  245
2018-01-09:2nd  334
2018-01-09:3rd  125
2018-01-08:1st  441
2018-01-08:2nd  263
2018-01-08:3rd  430
2018-01-07:1st  390
2018-01-07:2nd  456
2018-01-07:3rd  152

期望的结果:

            1st 2nd 3rd
2018-01-10  389 39  406
2018-01-09  245 334 125
2018-01-08  441 263 430
2018-01-07  390 456 152

我不确定从哪里开始;我不知道某种形式的Pivot是我的解决方案还是1How to convert aggregation results into columns?“这个”。我已经尝试将日期和第3次休息分组为每天两个条目。

2 个答案:

答案 0 :(得分:0)

此解决方案应该有效:

SELECT
    CAST(DATEADD(MINUTE, -390, TimeStamp) AS DATE) AS [Date]
    , SUM(CASE
        WHEN CAST(TimeStamp AS TIME) BETWEEN '06:30:00.000' AND '14:29:59.999'
        THEN 1 
        ELSE 0 
    END) AS [1st]
    , SUM(CASE 
        WHEN CAST(TimeStamp AS TIME) BETWEEN '14:30:00.000' AND '22:29:59.999'
        THEN 1 
        ELSE 0 
    END) AS [2nd]
    , SUM(CASE 
        WHEN CAST(TimeStamp AS TIME) < '06:30:00.000' 
            OR CAST(TimeStamp AS TIME) >= '22:30:00.000'
        THEN 1 
        ELSE 0 
    END) AS [3rd]
FROM Offload
GROUP BY CAST(DATEADD(MINUTE, -390, TimeStamp) AS DATE)

表格看起来像这样(我添加了一些其他日期和时间来测试):

ID          TimeStamp
----------- -----------------------
310963422   2018-01-09 22:31:58.000
310963422   2018-01-09 23:52:30.000
310963422   2018-01-10 00:01:02.000
310963422   2018-01-10 04:08:45.000
310963422   2018-01-10 06:35:23.000
310963627   2018-01-10 15:30:21.000
310963562   2018-01-10 15:29:47.000
310963595   2018-01-10 15:29:04.000
310963517   2018-01-10 15:28:21.000
310963548   2018-01-10 15:27:41.000
310963469   2018-01-10 15:27:02.000
310963500   2018-01-10 15:26:17.000
310963436   2018-01-10 15:25:39.000
310963422   2018-01-10 15:24:58.000
310963500   2018-01-10 22:26:17.000
310963436   2018-01-10 22:25:39.000
310963422   2018-01-10 22:31:58.000

它将返回

的结果
Date       1st         2nd         3rd
---------- ----------- ----------- -----------
2018-01-09 0           0           4
2018-01-10 1           11          1

需要注意的事项:我已经假设上午10:30到6:30的班次被视为之前日的一部分。如果您希望它成为第二天的一部分,请删除-390函数中DATEADD内的减号。

另外考虑用IIF函数替换CASE语句,我发现它使代码更具可读性,并且SQL Server Management Studio不喜欢调试CASE的问题。

如果有任何不清楚的地方,请发表评论。

答案 1 :(得分:0)

我最终创建了两列[Shift]和[ShiftDate]; [Shift]标识1st,2nd,3rd,[ShiftDate]使穿过午夜的3rd前进。克里斯(Kris)的回答使我处在正确的轨道上。谢谢!

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    con = cx_Oracle.connect('','','<service name>')
cx_Oracle.DatabaseError: ORA-01017: invalid username/password; logon denied

然后分组依据:

    CASE WHEN (CONVERT(CHAR(8), Timestamp, 114) between '06:30:00' and '14:30:00')        THEN '1'
         WHEN (CONVERT(CHAR(8), Timestamp, 114) between '14:30:00' and '22:30:00')        THEN '2'
         WHEN (CONVERT(CHAR(8), Timestamp, 114) between '22:30:00' and '24:00:00')        THEN '3'
         WHEN (CONVERT(CHAR(8), Timestamp, 114) between '00:00:00' and '06:30:00')        THEN '3'
              END AS [Shift]

   ,CASE WHEN (CONVERT(CHAR(8), Timestamp, 114) between '06:30:00' and '14:30:00')        THEN convert(varchar, CAST(TimeStamp AS DATE), 1)
         WHEN (CONVERT(CHAR(8), Timestamp, 114) between '14:30:00' and '22:30:00')        THEN convert(varchar, CAST(TimeStamp AS DATE), 1)
         WHEN (CONVERT(CHAR(8), Timestamp, 114) between '22:30:00' and '24:00:00')        THEN convert(varchar, CAST(DATEADD(DAY, 1, TimeStamp) AS DATE), 1)
         WHEN (CONVERT(CHAR(8), Timestamp, 114) between '00:00:00' and '06:30:00')        THEN convert(varchar, CAST(TimeStamp AS DATE), 1)
              END AS [ShiftDate]