自我加入?是上周工作的员工活跃于3周前-MYSQL

问题描述

我正尝试在生产时间数据集中添加一列,以告知上周工作的提供者是否也在三周前工作。当前数据集如下所示:

RowID | ProviderID | ClientID |     DOS    |   DOS (Week)  | Hours 
  1   | 1111111111 | 22222222 | 11/2/2020  |   11/1/2020   | 2.5 
  2   | 1111111111 | 33333333 | 11/5/2020  |   11/1/2020   | 1 
  3   | 1111111111 | 44444444 | 10/13/2020 |   10/11/2020  | 3 

我正在尝试使用“ y / n”或“ 1/0”作为值来增加一列“ Active 3 Weeks Prior”。对于上表,我们假设提供程序始于10/13/20。理想情况下,新列将像这样填充:

RowID | ProviderID | ClientID |     DOS    |   DOS (Week)  | Hours | Active 3 weeks Prior 
  1   | 1111111111 | 22222222 | 11/2/2020  |   11/1/2020   | 2.5   |   Yes              
  2   | 1111111111 | 33333333 | 11/5/2020  |   11/1/2020   | 1     |   Yes
  3   | 1111111111 | 44444444 | 10/13/2020 |   10/11/2020  | 3     |   No

一些额外的花絮:我们的组织将星期日作为一周的开始,因此DOS(星期)是服务日期之前的星期日。从到目前为止的内容来看,这里的解决方案似乎是一种自我连接,将基本生产记录汇总到每周的工作时间中,并与DOS(每周)的同一providerID记录进行比较-21。 >

我遇到的麻烦是:首先我是否处于自我连接的正确轨道上,以及如何根据查找匹配值的成功或失败生成y / n值。另外,我怀疑基于ProviderID和DOS(Week)的连接的加入可能存在缺陷吗?到目前为止,这就是我一直在玩的游戏。

请让我知道我是否可以完全澄清问题或遗漏非常明显的问题。我真的很感谢您的帮助,因为几天来我一直在努力寻找正确的搜索词以找到答案的线索。

解决方法

如果运行的是MySQL 8.0,则可以使用窗口函数和range规范:

select t.*,(
        max(providerid) over(
            partition by providerid 
            order by dos
            range between interval 3 week preceding and interval 3 week preceding
        ) is not null
    ) as active_3_weeks_before
from mytable t

从您的解释和数据来看,您所说的意思还早于三周还不是很清楚。对于每行,查询要执行的操作是检查是否存在与同一供应商并存在dos的另一行,该行恰好在当前行的dos前三周。这很容易适应其他要求。


编辑:如果要在最近3周内检查任何记录,可以将窗口范围更改为:

range between interval 3 week preceding and interval 1 day preceding

如果要在没有窗口功能的MySQL

select t.*,exists (
        select 1
        from mytable t1
        where 
            t1.providerid = t.provider_id
            and t1.dos >= t.dos - interval 3 week
            and t1.dos <  t.dos
    ) as active_3_weeks_before
from mytable t