T-SQL 改变元素分组
T-SQL grouping by changing elements
希望你们一切安好!
我的第一个 post,我需要一些关于 T-SQL 的帮助。
我如何标记(计算发生了多少 PICK_STATE_CHANGES)从一个事件到另一个事件的事件列表?
例如,我想将 'LABM_PICK_SCAN_LOCATION' 和第一个 'LABM_PICK_DECLARE_TROLLEY_FULL' 之间的列 oel_class
中的所有行标记(创建虚拟容器)为 1,然后每个下一个 'LABM_PICK_SCAN_LOCATION'到 'LABM_PICK_DECLARE_TROLLEY_FULL' 之前的 1 + 1:
user event_time oel_class
102480 2020-03-25 12:09:58 LABM_PICK_SCAN_LOCATION <-- this is the starting point of the first virtual container (1)
102480 2020-03-25 12:10:23 TM_TROLLEY_COLLECT - (1)
102480 2020-03-25 12:12:16 PICK_STATE_CHANGE - (1)
102480 2020-03-25 12:12:39 PICK_STATE_CHANGE - (1)
102480 2020-03-25 12:13:44 PICK_STATE_CHANGE - (1)
102480 2020-03-25 12:14:09 PICK_STATE_CHANGE - etc.
102480 2020-03-25 12:14:39 PICK_STATE_CHANGE
102480 2020-03-25 12:15:20 PICK_STATE_CHANGE
102480 2020-03-25 12:15:20 PICK_STATE_CHANGE
102480 2020-03-25 12:16:17 PICK_STATE_CHANGE
102480 2020-03-25 12:16:51 PICK_STATE_CHANGE
102480 2020-03-25 12:17:27 PICK_STATE_CHANGE
102480 2020-03-25 12:18:02 PICK_STATE_CHANGE
102480 2020-03-25 12:18:02 LABM_PICK_DECLARE_TROLLEY_FULL <-- this is the end of the virtual container
102480 2020-03-25 12:18:48 TM_LOC_CHANGE <-- ignore this
102480 2020-03-25 12:19:28 LABM_PICK_DECLARE_TROLLEY_FULL <-- ignore this
102480 2020-03-25 12:21:40 TM_TROLLEY_PARK <-- ignore this
102480 2020-03-25 12:21:40 LABM_PICK_SELECT_PACK_AREA <-- ignore this
102480 2020-03-25 12:21:48 LABM_PICK_SCAN_LOCATION <-- this is the start of the second virtual container (2)
102480 2020-03-25 12:21:55 TM_TROLLEY_COLLECT - (2)
102480 2020-03-25 12:24:57 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:25:55 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:26:33 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:27:15 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:27:52 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:28:47 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:29:38 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:29:38 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:30:03 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:30:53 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:33:16 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:35:52 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:35:52 LABM_PICK_DECLARE_TROLLEY_FULL <-- this is the end of the virtual container
102480 2020-03-25 12:44:05 TM_TROLLEY_PARK <-- ignore this
etc. 3, 4, 5, ...
有什么想法吗?我想做一个 CASE 但我怎么说在特定事件旁边放一个 1,然后在 'virtual container'?
旁边放一个 1
我正在使用 SQL Server 2017。
如果我没听错,你可以使用 lead()
和累积 sum()
:
select t.*,
case when oel_class in ('TM_TROLLEY_COLLECT', 'PICK_STATE_CHANGE')
then sum(case when oel_class = 'TM_TROLLEY_COLLECT' and lead_oel_class = 'PICK_STATE_CHANGE' then 1 else 0 end) over(partition by user order by event_time)
end as grp
from (
select t.*,
lead(oel_class) over(partition by user order by event_time) lead_oel_class
from mytable t
) t
希望你们一切安好!
我的第一个 post,我需要一些关于 T-SQL 的帮助。
我如何标记(计算发生了多少 PICK_STATE_CHANGES)从一个事件到另一个事件的事件列表?
例如,我想将 'LABM_PICK_SCAN_LOCATION' 和第一个 'LABM_PICK_DECLARE_TROLLEY_FULL' 之间的列 oel_class
中的所有行标记(创建虚拟容器)为 1,然后每个下一个 'LABM_PICK_SCAN_LOCATION'到 'LABM_PICK_DECLARE_TROLLEY_FULL' 之前的 1 + 1:
user event_time oel_class
102480 2020-03-25 12:09:58 LABM_PICK_SCAN_LOCATION <-- this is the starting point of the first virtual container (1)
102480 2020-03-25 12:10:23 TM_TROLLEY_COLLECT - (1)
102480 2020-03-25 12:12:16 PICK_STATE_CHANGE - (1)
102480 2020-03-25 12:12:39 PICK_STATE_CHANGE - (1)
102480 2020-03-25 12:13:44 PICK_STATE_CHANGE - (1)
102480 2020-03-25 12:14:09 PICK_STATE_CHANGE - etc.
102480 2020-03-25 12:14:39 PICK_STATE_CHANGE
102480 2020-03-25 12:15:20 PICK_STATE_CHANGE
102480 2020-03-25 12:15:20 PICK_STATE_CHANGE
102480 2020-03-25 12:16:17 PICK_STATE_CHANGE
102480 2020-03-25 12:16:51 PICK_STATE_CHANGE
102480 2020-03-25 12:17:27 PICK_STATE_CHANGE
102480 2020-03-25 12:18:02 PICK_STATE_CHANGE
102480 2020-03-25 12:18:02 LABM_PICK_DECLARE_TROLLEY_FULL <-- this is the end of the virtual container
102480 2020-03-25 12:18:48 TM_LOC_CHANGE <-- ignore this
102480 2020-03-25 12:19:28 LABM_PICK_DECLARE_TROLLEY_FULL <-- ignore this
102480 2020-03-25 12:21:40 TM_TROLLEY_PARK <-- ignore this
102480 2020-03-25 12:21:40 LABM_PICK_SELECT_PACK_AREA <-- ignore this
102480 2020-03-25 12:21:48 LABM_PICK_SCAN_LOCATION <-- this is the start of the second virtual container (2)
102480 2020-03-25 12:21:55 TM_TROLLEY_COLLECT - (2)
102480 2020-03-25 12:24:57 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:25:55 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:26:33 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:27:15 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:27:52 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:28:47 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:29:38 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:29:38 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:30:03 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:30:53 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:33:16 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:35:52 PICK_STATE_CHANGE - (2)
102480 2020-03-25 12:35:52 LABM_PICK_DECLARE_TROLLEY_FULL <-- this is the end of the virtual container
102480 2020-03-25 12:44:05 TM_TROLLEY_PARK <-- ignore this
etc. 3, 4, 5, ...
有什么想法吗?我想做一个 CASE 但我怎么说在特定事件旁边放一个 1,然后在 'virtual container'?
旁边放一个 1我正在使用 SQL Server 2017。
如果我没听错,你可以使用 lead()
和累积 sum()
:
select t.*,
case when oel_class in ('TM_TROLLEY_COLLECT', 'PICK_STATE_CHANGE')
then sum(case when oel_class = 'TM_TROLLEY_COLLECT' and lead_oel_class = 'PICK_STATE_CHANGE' then 1 else 0 end) over(partition by user order by event_time)
end as grp
from (
select t.*,
lead(oel_class) over(partition by user order by event_time) lead_oel_class
from mytable t
) t