在 SQL 服务器中不存在具有多个条件和间接唯一 ID

NOT EXISTS with multiple criteria and indirect unique id in SQL Server

我很难理解 SQL 服务器中 NOT EXISTS 的这个查询。

我的同事帮助我完成了这个查询,效果很好。基本上有 3 个 table,我想看看 work_q_id 是否存在于 t_allocation table 中,但是 t_allocation 没有列(键)匹配 work_q_id,这就是为什么我必须用 pick table 加入它。简而言之,它是这样工作的:

work -> pick -> allocation

我的问题是 NOT EXISTS 如何知道 t_allocation 中不存在哪个 work_q_idt_allocation 甚至没有那一列?

Pick table 有 work_q_id 用于加入工作 table 和 t_allocation 也有 pick_id 我曾经加入 pick table 以识别不存在的 work_q_ids

有人可以帮我理解这个概念吗?

提前致谢

select 
    wkq.wh_id, wkq.work_q_id
from 
    work wkq with (NOLOCK)
inner join 
    pick pkd WITH (NOLOCK) on pkd.work_q_id = wkq.work_q_id
                           and pkd.wh_id = wkq.wh_id
where 
    wkq.work_type in ('72')
    and wkq.work_status = 'U'
    and (wkq.pick_ref_number like ('%PICK_PRIME%')
         or wkq.description like 'TopOff%')
    and pkd.status = 'RELEASED'
    --and (CONVERT(VARCHAR , CONVERT(DATETIME , wkq.datetime_stamp AT TIME ZONE ('UTC') AT TIME ZONE ('Eastern Standard Time')) , 120)) <= '2021-05-26 15:33:00' 
    and (CONVERT(VARCHAR , CONVERT(DATETIME , wkq.datetime_stamp AT TIME ZONE ('UTC') AT TIME ZONE ('Eastern Standard Time')) , 120)) <= DATEADD(hh, -24, (CONVERT(VARCHAR , CONVERT(DATETIME , GETDATE() AT TIME ZONE ('UTC') AT TIME ZONE ('Eastern Standard Time')) , 120)))
    and not exists (select 1 from t_allocation alc WITH (NOLOCK)
                    WHERE pkd.wh_id = alc.wh_id 
                AND pkd.pick_id = alc.pick_id
                AND pkd.work_q_id = wkq.work_q_id)

试试这个:

select 
            wkq.wh_id
        ,   wkq.work_q_id
from        work            wkq
inner join  pick            pkd     on  pkd.work_q_id   =   wkq.work_q_id
                                    and pkd.wh_id       =   wkq.wh_id
left join   t_allocation    alc     on  alc.pick_id     =   pkd.pick_id
                                    
where       alc.pick_id IS NULL
        and wkq.work_type   in  ('72')
        and wkq.work_status =   'U'
        and (
                    wkq.pick_ref_number like    '%PICK_PRIME%'
                or  wkq.description     like    'TopOff%'
            )
        and pkd.status      =   'RELEASED'
        and (
                                    CONVERT(VARCHAR , CONVERT(DATETIME , wkq.datetime_stamp AT TIME ZONE ('UTC') AT TIME ZONE ('Eastern Standard Time')) , 120)) <= 
                DATEADD(hh, -24, (  CONVERT(VARCHAR , CONVERT(DATETIME , GETDATE()          AT TIME ZONE ('UTC') AT TIME ZONE ('Eastern Standard Time')) , 120))
            )

在您的查询中,EXISTS 是一个 correlated 子查询:换句话说,它有一个或多个外部引用其余的查询。

只看相关部分:

from 
    work wkq
inner join 
    pick pkd......

所以 wkqpkdouter table references


where 
....
    not exists (select 1

你在 EXISTS 查询中实际 select 是无关紧要的,所以 1 没问题,NOT 显然反转 EXISTS


 from t_allocation alc WITH (NOLOCK)

现在alc内部参考


                    WHERE pkd.wh_id = alc.wh_id 
                AND pkd.pick_id = alc.pick_id

这两行是内部参考和外部参考之间的相关性,所以EXISTS只会挑选出符合这些条件的行


                AND pkd.work_q_id = wkq.work_q_id)

这很有趣。不是相关性,因为没有内部引用,只有外部。

这是一个启动过滤器:如果 outer-reference 条件为真,EXISTS 将只有 return 行