我是SQL Server的新手(到目前为止已有3天的经验,但是我对如何在excel之外完成此操作感到困惑,如果很难解释,对不起。
表格底部示例:
我有一个每分钟带有时间戳,零件计数器和错误代码的表。我目前将零件计数合并到15分钟范围内,并将该范围的总数与以下内容组合在一起:
SELECT
DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 15) * 15, '20000101') as Date_Time,
MAX(Part_Count) - MIN(Part_Count) AS PartsMade
FROM
[SMP].[dbo].[33_TestImport]
WHERE
[DateTime] >= DATEADD(HOUR, DATEDIFF(HOUR, 0, GETDATE()) - 24, 0)
GROUP BY
DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 15) * 15, '20000101')
现在我要添加到此,再添加一行(现在)。
[PV_alarm将成为一个数字,在这一点上,我想计数直到part_count增加的时间,pv_alarm可能在第一次触发和part_count再次增加之间发生多次更改。
so:
要更清楚:表格
DateTime Part_Count Alarm_Light PV_Alarm Runtime_M
-----------------------------------------------------------------------
2020-03-18 20:16:06.040 340946 0 0 127076
2020-03-18 20:17:06.040 340953 0 0 127077
2020-03-18 20:18:06.040 340960 0 0 127078
2020-03-18 20:19:06.040 340967 0 0 127079
2020-03-18 20:20:06.040 340973 0 0 127080
2020-03-18 20:21:06.040 340978 1 8 127081 <--- timer would start here
2020-03-18 20:22:06.040 340978 1 8 127081
2020-03-18 20:23:06.040 340978 1 8 127081
2020-03-18 20:24:06.040 340978 1 8 127081
2020-03-18 20:25:06.040 340978 1 8 127081
2020-03-18 20:26:06.040 340978 1 8 127081
2020-03-18 20:27:06.040 340978 1 8 127081
2020-03-18 20:28:06.040 340978 1 8 127081
2020-03-18 20:29:06.040 340978 1 8 127081
2020-03-18 20:30:06.040 340978 1 8 127081
2020-03-18 20:31:06.040 340978 1 8 127081
2020-03-18 20:32:06.040 340978 1 8 127081
2020-03-18 20:33:06.040 340978 1 8 127081
2020-03-18 20:34:06.040 340978 1 8 127081
2020-03-18 20:35:06.040 340978 1 8 127081
2020-03-18 20:36:06.040 340978 1 8 127081
2020-03-18 20:37:06.040 340978 1 8 127081
2020-03-18 20:38:06.040 340978 1 8 127081
2020-03-18 20:39:06.040 340978 1 8 127081
2020-03-18 20:40:06.040 340978 1 8 127081
2020-03-18 20:41:06.040 340978 1 8 127081
2020-03-18 20:42:06.040 340978 1 8 127081
2020-03-18 20:43:06.040 340978 1 8 127081
2020-03-18 20:44:06.040 340978 1 8 127081
2020-03-18 20:45:06.040 340978 1 8 127081
2020-03-18 20:46:06.040 340978 1 8 127081
2020-03-18 20:47:06.040 340978 1 8 127081
2020-03-18 20:48:06.040 340978 1 8 127081
2020-03-18 20:49:06.040 340978 1 8 127081
2020-03-18 20:50:06.040 340978 1 8 127081
2020-03-18 20:51:06.040 340978 1 8 127081
2020-03-18 20:52:06.040 340978 1 8 127081
2020-03-18 20:53:06.040 340978 1 8 127081
2020-03-18 20:54:06.040 340978 1 8 127081
2020-03-18 20:55:06.040 340978 1 8 127081
2020-03-18 20:56:06.040 340978 1 8 127081
2020-03-18 20:57:06.040 340978 1 8 127081
2020-03-18 20:58:06.040 340978 1 8 127081
2020-03-18 20:59:06.040 340978 1 8 127081
2020-03-18 21:00:06.040 340978 1 8 127081
2020-03-18 21:01:06.040 340978 1 8 127081
2020-03-18 21:02:06.040 340978 1 8 127081
2020-03-18 21:03:06.040 340978 1 8 127081
2020-03-18 21:04:06.040 340978 1 8 127081
2020-03-18 21:05:06.040 340978 1 8 127081
2020-03-18 21:06:06.040 340978 1 8 127081
2020-03-18 21:07:06.040 340978 1 8 127081
2020-03-18 21:08:06.040 340978 1 8 127081
2020-03-18 21:09:06.040 340978 1 8 127081
2020-03-18 21:10:06.040 340978 1 8 127081
2020-03-18 21:11:06.040 340978 1 8 127081
2020-03-18 21:12:06.040 340978 0 0 127081
2020-03-18 21:13:06.040 340978 0 0 127081
2020-03-18 21:14:06.040 340978 0 0 127081
2020-03-18 21:15:06.040 340978 0 0 127081
2020-03-18 21:16:06.040 340978 0 0 127081
2020-03-18 21:17:06.040 340978 0 0 127081
2020-03-18 21:18:06.040 340978 0 0 127081
2020-03-18 21:19:06.040 340978 0 0 127081
2020-03-18 21:20:06.040 340984 0 0 127082 <---- timer ends
结果将是这样,但是如果它也必须是它自己的结果,那么我以后可以与上面的选择结合使用,就可以了
Date_Time PartsMade Downtime
2020-03-18 20:45:00.000 0
2020-03-18 21:00:00.000 0
2020-03-18 21:15:00.000 68 00:59:00
2020-03-18 21:30:00.000 97
这里尝试。在this SQLFiddle上查看。
WITH X AS (
SELECT [DateTime], part_count, pv_alarm, case when pv_alarm>0 and (lag(pv_alarm) over (order by DateTime))=0
then 'START' else null end as State
from mydata as M1),
XX AS (
SELECT * from X where State IS NOT NULL
),
Y AS (
SELECT [DateTime], part_count, pv_alarm, (lag(part_count) over (order by DateTime)) as prev_part_Count
from MyData as M2
),
YY AS (
SELECT Y.[DateTime],Y.part_count,Y.pv_alarm,'END' AS State FROM Y
inner join XX on Y.prev_part_count=XX.part_count
WHERE Y.part_count <> Y.prev_part_count
)
SELECT * FROM XX
UNION ALL SELECT * FROM YY
讨论:
X
将值[[START分配给行中的列State
,其中pv_alarm从上一行的零更改为该行的非零。XX
”仅选择分配了State
Y
是一个帮助程序,它将上一行的part_count与该行的part count一起带来。您可能会认为它可以折叠为YY
,但是LAG()
函数必须位于SELECT
或ORDER BY
子句中,而不是WHERE
子句中。YY
从Y
中获取零件数已更改的行,将先前的零件数与CTE X
相匹配,以确保我们保持正确的跨度,并分配值State
。最后,非CTE选择仅返回DateTime part_count pv_alarm State
-------- ---------- -------- -----
2020-03-18T20:21:06.04Z 340978 8 START
2020-03-18T21:20:06.04Z 340984 0 END