【问题标题】:SQL Flag Rows Occurring 2 Hours After Previous FlagSQL 标志行在前一个标志之后 2 小时出现
【发布时间】:2020-10-12 20:17:17
【问题描述】:

由于天线过于敏感,我有一些混乱的 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', N'Decontamination', CAST(N'2020-10-10T06:30:00.0000000' AS DateTime2), N'1')
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', N'Decontamination', CAST(N'2020-10-11T14:30:00.0000000' AS DateTime2), N'1')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'A', N'Washer', N'Washer', CAST(N'2020-10-11T14:45:00.0000000' AS DateTime2), N'0')
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', N'Decontamination', CAST(N'2020-10-11T15:15:00.0000000' AS DateTime2), N'0')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'A', N'Other', N'Decontamination', CAST(N'2020-10-11T23:30:00.0000000' AS DateTime2), N'1')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'A', N'Washer', N'Washer', CAST(N'2020-10-12T00:15:00.0000000' AS DateTime2), N'0')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'A', N'Other', N'Decontamination', CAST(N'2020-10-12T00:45:00.0000000' AS DateTime2), N'0')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'A', N'Other', N'Decontamination', CAST(N'2020-10-13T16:00:00.0000000' AS DateTime2), N'1')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'A', N'Other', N'Decontamination', CAST(N'2020-10-13T16:30:00.0000000' AS DateTime2), N'0')
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', N'Decontamination', CAST(N'2020-10-14T13:30:00.0000000' AS DateTime2), N'1')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'B', N'Other', N'Decontamination', CAST(N'2020-10-12T08:30:00.0000000' AS DateTime2), N'1')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'B', N'Decontamination', N'Decontamination', CAST(N'2020-10-12T14:30:00.0000000' AS DateTime2), N'1')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'B', N'Washer', N'Washer', CAST(N'2020-10-12T14:45:00.0000000' AS DateTime2), N'0')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'B', N'Decontamination', N'Decontamination', CAST(N'2020-10-12T15:15:00.0000000' AS DateTime2), N'0')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'B', N'Decontamination', N'Decontamination', CAST(N'2020-10-12T18:00:00.0000000' AS DateTime2), N'1')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'B', N'Washer', N'Washer', CAST(N'2020-10-13T18:15:00.0000000' AS DateTime2), N'0')
GO
INSERT [dbo].[RFID SQL Problem Sample Data] ([Item], [Station_Type], [Station_Name], [Timestamp], [Trying_to_Create_this_Flag_Column]) VALUES (N'B', N'Decontamination', N'Decontamination', CAST(N'2020-10-13T19:00:00.0000000' AS DateTime2), N'1')
GO

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

项目 | Station_Type |站名 |时间戳 | Trying_to_Create_this_Flag_Column :--- | :---------------- | :---------------- | :---------------------------- | :-------------------------------- 一个 |去污 |去污 | 2020-10-10 06:30:00.0000000 | 1 一个 |去污 |去污 | 2020-10-11 14:30:00.0000000 | 1 一个 |垫圈 |垫圈 | 2020-10-11 14:45:00.0000000 | 0 一个 |去污 |去污 | 2020-10-11 15:15:00.0000000 | 0 一个 |其他 |去污 | 2020-10-11 23:30:00.0000000 | 1 一个 |垫圈 |垫圈 | 2020-10-12 00:15:00.0000000 | 0 一个 |其他 |去污 | 2020-10-12 00:45:00.0000000 | 0 一个 |其他 |去污 | 2020-10-13 16:00:00.0000000 | 1 一个 |其他 |去污 | 2020-10-13 16:30:00.0000000 | 0 一个 |去污 |去污 | 2020-10-14 13:30:00.0000000 | 1 乙|其他 |去污 | 2020-10-12 08:30:00.0000000 | 1 乙|去污 |去污 | 2020-10-12 14:30:00.0000000 | 1 乙|垫圈 |垫圈 | 2020-10-12 14:45:00.0000000 | 0 乙|去污 |去污 | 2020-10-12 15:15:00.0000000 | 0 乙|去污 |去污 | 2020-10-12 18:00:00.0000000 | 1 乙|垫圈 |垫圈 | 2020-10-13 18:15:00.0000000 | 0 乙|去污 |去污 | 2020-10-13 19:00:00.0000000 | 1

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

项目 |循环 :--- | -----: 一个 | 5 乙| 4

这怎么可能完成?

【问题讨论】:

    标签: sql sql-server datetime recursive-query sql-server-2019


    【解决方案1】:

    如果我没听错,你需要递归查询:

    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

    【讨论】:

      【解决方案2】:

      试试这个,

      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
      

      【讨论】:

        猜你喜欢
        • 2020-01-27
        • 1970-01-01
        • 2021-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-24
        相关资源
        最近更新 更多