微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

前一个标志后2小时出现SQL标志行

如何解决前一个标志后2小时出现SQL标志行

由于天线过于敏感,我的RFID数据有些混乱。有一个物理过程可以跟踪一个周期中通过不同站点的RFID标签。带有RFID标签的物品一天可以在整个循环中移动超过一次,但是极不可能在第一次读取后的两个小时之内启动循环。

我正在尝试创建一个标志列以确定某个项目的新周期何时开始,或者返回一个项目经过一个周期的次数的计数。

以下是一些示例数据:

CREATE TABLE [dbo].[samplerfiddata](
    [Item] [nvarchar](50) NOT NULL,[Station_Type] [nvarchar](50) NOT NULL,[Station_Name] [nvarchar](50) NOT NULL,[Timestamp] [datetime2](7) NOT NULL,[Trying_to_Create_this_Flag_Column] [nvarchar](50) NOT NULL
) ON [PRIMARY]
GO
INSERT [dbo].[RFID sql Problem Sample Data] ([Item],[Station_Type],[Station_Name],[Timestamp],[Trying_to_Create_this_Flag_Column]) VALUES (N'A',N'Decontamination',CAST(N'2020-10-10T06:30:00.0000000' AS DateTime2),N'1')
GO
INSERT [dbo].[RFID sql Problem Sample Data] ([Item],CAST(N'2020-10-11T14:30:00.0000000' AS DateTime2),N'Washer',CAST(N'2020-10-11T14:45:00.0000000' AS DateTime2),N'0')
GO
INSERT [dbo].[RFID sql Problem Sample Data] ([Item],CAST(N'2020-10-11T15:15:00.0000000' AS DateTime2),N'Other',CAST(N'2020-10-11T23:30:00.0000000' AS DateTime2),CAST(N'2020-10-12T00:15:00.0000000' AS DateTime2),CAST(N'2020-10-12T00:45:00.0000000' AS DateTime2),CAST(N'2020-10-13T16:00:00.0000000' AS DateTime2),CAST(N'2020-10-13T16:30:00.0000000' AS DateTime2),CAST(N'2020-10-14T13:30:00.0000000' AS DateTime2),[Trying_to_Create_this_Flag_Column]) VALUES (N'B',CAST(N'2020-10-12T08:30:00.0000000' AS DateTime2),CAST(N'2020-10-12T14:30:00.0000000' AS DateTime2),CAST(N'2020-10-12T14:45:00.0000000' AS DateTime2),CAST(N'2020-10-12T15:15:00.0000000' AS DateTime2),CAST(N'2020-10-12T18:00:00.0000000' AS DateTime2),CAST(N'2020-10-13T18:15:00.0000000' AS DateTime2),CAST(N'2020-10-13T19:00:00.0000000' AS DateTime2),N'1')
GO

在此数据中,我们在整个周期中移动了两个不同的项目,并捕获了所有场景。新周期的业务逻辑定义为RFID天线(站)读取的项目,其中站类型=去污或站名称=去污,并且自从上一次第一次读取周期以来已经超过两个小时

Item | Station_Type    | Station_Name    | Timestamp                   | Trying_to_Create_this_Flag_Column
:--- | :-------------- | :-------------- | :-------------------------- | :--------------------------------
A    | Decontamination | Decontamination | 2020-10-10 06:30:00.0000000 | 1                                
A    | Decontamination | Decontamination | 2020-10-11 14:30:00.0000000 | 1                                
A    | Washer          | Washer          | 2020-10-11 14:45:00.0000000 | 0                                
A    | Decontamination | Decontamination | 2020-10-11 15:15:00.0000000 | 0                                
A    | Other           | Decontamination | 2020-10-11 23:30:00.0000000 | 1                                
A    | Washer          | Washer          | 2020-10-12 00:15:00.0000000 | 0                                
A    | Other           | Decontamination | 2020-10-12 00:45:00.0000000 | 0                                
A    | Other           | Decontamination | 2020-10-13 16:00:00.0000000 | 1                                
A    | Other           | Decontamination | 2020-10-13 16:30:00.0000000 | 0                                
A    | Decontamination | Decontamination | 2020-10-14 13:30:00.0000000 | 1                                
B    | Other           | Decontamination | 2020-10-12 08:30:00.0000000 | 1                                
B    | Decontamination | Decontamination | 2020-10-12 14:30:00.0000000 | 1                                
B    | Washer          | Washer          | 2020-10-12 14:45:00.0000000 | 0                                
B    | Decontamination | Decontamination | 2020-10-12 15:15:00.0000000 | 0                                
B    | Decontamination | Decontamination | 2020-10-12 18:00:00.0000000 | 1                                
B    | Washer          | Washer          | 2020-10-13 18:15:00.0000000 | 0                                
B    | Decontamination | Decontamination | 2020-10-13 19:00:00.0000000 | 1                                

最终,我正在尝试返回如下所示的结果集:

item | cycles
:--- | -----:
A    |      5
B    |      4

这怎么完成?

解决方法

如果我正确地关注您,则需要递归查询:

with 
    data as (
        select item,station_type,station_name,timestamp,row_number() over(partition by item order by timestamp) rn
        from samplerfiddata sf
    ),cte as (
        select d.*,timestamp first_timestamp 
        from data d 
        where rn = 1
        union all
        select d.*,case when 'Decontamination' in (d.station_type,d.station_name) and d.timestamp > dateadd(hour,2,c.first_timestamp)
                then d.timestamp
                else c.timestamp
            end
        from cte c
        inner join data d on d.item = c.item and d.rn = c.rn + 1
    )
select *
from cte
order by item,timestamp

这个想法是迭代地遍历每个item的数据集,同时跟踪最后一个循环的开始(此处别名为first_timestamp);当遇到“净化”事件比上一个事件晚两个小时以上时,周期时间戳记将重置。

您可以通过在外部查询中使用聚合来获取周期数,例如:

select item,count(*) cnt_cycles
from cte
where timestamp = first_timestamp
group by item

Demo on DB Fiddle

,

尝试一下,

with CTE as
(
select *,lead([Timestamp])over(partition by [Item] order by[Timestamp])lagtime
from [dbo].[samplerfiddata]
where Station_Type='Decontamination' or Station_Name='Decontamination'
)

select item,sum(case when lagtime is null then 1
when datediff(MINUTE,[Timestamp],lagtime)>=60 then 1 else 0 end) as cycles

from CTE
group by item

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。