【问题标题】:Return dates on which a team member was called back in more than once团队成员多次被召回的返回日期
【发布时间】:2020-08-30 09:47:06
【问题描述】:

我在 Azure SQL DB (SQL Server) 中工作,但自从我开始处理这个问题以来,我遇到了一个变得越来越复杂的查询问题。不幸的是,我正在处理的计时数据不是最干净的。

问题陈述:
返回结果显示被叫来工作的团队成员(特定的呼入 PaycodeID - “CB”),然后被送回家并转移到待命状态(这会创建一个具有不同待命 PaycodeID 的新行 - “ OC”),后来又被召回工作(第三行带有呼入 PaycodeID - “CB”)。用简单的英语来说,要求是找到一个值班员工在轮班期间不止一次被叫到工作的实例。

数据集:

| RowID | EmployeeID | Shift Date | StartDT             | EndDT               | PaycodeID |
|-------|------------|------------|---------------------|---------------------|-----------|
| 1     | 123        | 2020-02-13 | 2020-02-13 17:30:00 | 2020-02-13 19:00:00 | CB        |
| 2     | 123        | 2020-02-13 | 2020-02-13 19:00:00 | 2020-02-13 23:00:00 | OC        |
| 3     | 123        | 2020-02-13 | 2020-02-13 23:00:00 | 2020-02-14 03:00:00 | CB        |
| 4     | 456        | 2020-01-01 | 2020-01-01 06:00:00 | 2020-01-01 09:30:00 | OC        |
| 5     | 456        | 2020-01-01 | 2020-01-01 09:30:00 | 2020-01-01 12:00:00 | CB        |
| 6     | 456        | 2020-01-01 | 2020-01-01 12:30:00 | 2020-01-01 16:45:00 | CB        |
| 7     | 456        | 2020-01-01 | 2020-01-01 16:45:00 | 2020-01-01 18:00:00 | OC        |

我试过的 T-SQL 查询:

SELECT 

    ,[EmployeeID]
    ,[Shift Date]
    ,SUM(
        CASE WHEN [PaycodeID] = "OC"
        THEN 1
        ELSE 0
        END
        )
     AS [On-Call Count]
    ,SUM(
        CASE WHEN [PaycodeID] = "CB"
        THEN 1
        ELSE 0
        END
         ) 
        AS [Call Back Count]

FROM 
    #OnCallTable

GROUP BY [Employee ID], [Shift Date]
ORDER BY [Employee ID], [Shift Date]

此查询的结果:

| EmployeeID | Shift Date | On-Call Count | Call Back Count |
|------------|------------|---------------|-----------------|
| 123        | 2020-02-13 | 1             | 2               |
| 456        | 2020-01-01 | 2             | 2               |

然后我计划选择 [Call Back Count] > 1 的 EmployeeID 和 Shift Date。但是,这将返回上述结果集中的两条记录,而只返回第一行。如果您回顾一下我的原始数据集,员工 456 只被叫到工作一次,并以两个“CB”行结束,因为他们在 12:00:00 下班休息。我正在尝试设计一个查询,该查询仅返回员工具有“OC”条目的班次,其中时间戳位于两个或多个“CB”条目之间。

任何关于如何解决这个问题的想法将不胜感激。

【问题讨论】:

    标签: sql sql-server tsql select window-functions


    【解决方案1】:

    如果我没听错的话,你可以用lead()lag() 解决这个问题:

    select employeeID, shiftDate
    from (
        select 
            oc.*,
            lead(startDT)   over(partition by employeeID, shiftDate order by rowID) leadStartDT,
            lead(paycodeID) over(partition by employeeID, shiftDate order by rowID) leadPaycodeID,
            lag(endDT)      over(partition by employeeID, shiftDate order by rowID) lagEndDT,
            lag(paycodeID)  over(partition by employeeID, shiftDate order by rowID) lagPaycodeID
        from #onCallTable oc
    ) t
    where 
        paycodeID = 'OC'
        and lagPaycodeID = 'CB' 
        and leadPaycodeID = 'CB'
        and lagEndDT = startDT
        and leadStartDT = endDT
    

    这会带来带有支付码 OC 的行,周围是支付码 CB,并且其日期与周围的记录是连续的。

    【讨论】:

    • lead() 和 lag() 符合我的要求。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    相关资源
    最近更新 更多