我的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是我的解决方案还是1:How to convert aggregation results into columns?“这个”。我已经尝试将日期和第3次休息分组为每天两个条目。
答案 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]