【问题标题】:Not exists clause isn't working as expectedNot exists 子句未按预期工作
【发布时间】:2022-01-13 00:03:48
【问题描述】:

我想搜索没有任何分析师 (cod_role_acces) 为其工作的所有公司 (niu_lds)。

示例:假设有一家公司 X,有 3 名员工。其中一位是分析师。我不希望那家公司出现在我的结果中。但如果 Y 公司有 2 名员工,而且他们都不是“分析师”,那么我希望这家公司出现在结果中。

这是我的查询:

SELECT DISTINCT
    a.name_pers as "First Name",
    a.last_pers as "Last Name",
    a.id as "# account",
    a.cod_role_acces as "Profile", 
    a.niu_lds as "Company", 
    b.cod_missn as "Mission", 
    
FROM sr.c_r_v_obt_cp_util a inner join ods.c_od_missn_ld b on a.niu_lds = b.niu_lds

WHERE a.cod_eta_util in ('VER', 'APPR')
and a.id_cod_sr_alim = '2'
and b.cod_missn = 'PHA'

 and not exists (select null
                 from sr.c_r_v_obt_cp_util c 
                 where c.niu_lds = a.niu_lds
                 and a.cod_role_acces = 'ANALYST'
                );

我的问题是它让我拥有“分析师”的“公司”!我想查看所有没有归属于该公司的 'ANALYST'(cod_role_access) 的公司 (niu_lds)。

我已经问过这个问题,有人帮了我很多,但我仍然没有得到预期的输出。

我的第一个问题:SQL query to check if a value isn't present

谢谢

【问题讨论】:

标签: sql plsql


【解决方案1】:

我相信 Romeo 将 null 更改为 1 的答案可能会让你到达那里。

如果没有,并且您想直观地查看发生了什么比较,您可以将 not exists 函数转换为左连接,这样您就可以看到值的放置位置。

使用上一篇文章中的测试示例 -

with test (company, ename, profile) as
      (select 'BMW', 'Scott', 'Analyst' union all
       select 'BMW', 'King' , 'Manager' union all
      select 'BMW', 'Mike' , 'Clerk'  union all
      select 'SAP', 'John' , 'Clerk' union all
      select 'SAP', 'Fred' , 'Manager' 
    )
  select a.company, a.ename, a.profile, b.analyst
  from test a
  left join (select 1 as analyst, company
        from test
        where profile = 'Analyst') b
        on b.company = a.company

以下是返回-

COMPANY ENAME PROFILE ANALYST
BMW Scott Analyst 1
BMW King Manager 1
BMW Mike Clerk 1
SAP John Clerk null
SAP Fred Manager null

您可以从这里看到所有 BMW 都被标记为 Analyst,如果您想构建左连接而不是不存在但“隐藏”标记为 Analyst 的列,请添加“其中 b.analyst 为空”并从 select 语句中删除 b.analyst -

with test (company, ename, profile) as
      (select 'BMW', 'Scott', 'Analyst' union all
       select 'BMW', 'King' , 'Manager' union all
      select 'BMW', 'Mike' , 'Clerk'  union all
      select 'SAP', 'John' , 'Clerk' union all
      select 'SAP', 'Fred' , 'Manager' 
    )
  select a.company, a.ename, a.profile
  from test a
  left join (select 1 as analyst, company
        from test
        where profile = 'Analyst') b
        on b.company = a.company
where b.analyst is null

这将返回预期的表 -

COMPANY ENAME PROFILE
SAP John Clerk
SAP Fred Manager

编辑添加了 OP 的等价物:

这些应该与最初发布的逻辑和您的代码相匹配 -

存在 AnalystFlag -

SELECT DISTINCT
    a.name_pers as "First Name",
    a.last_pers as "Last Name",
    a.id as "# account",
    a.cod_role_acces as "Profile", 
    a.niu_lds as "Company", 
    b.cod_missn as "Mission", 
    c.analyst as "AnalystFlag"
    
FROM sr.c_r_v_obt_cp_util a 
  inner join ods.c_od_missn_ld b 
    on a.niu_lds = b.niu_lds
  left join (select distinct 1 as analyst, niu_lds
                 from sr.c_r_v_obt_cp_util
                 where cod_role_acces = 'ANALYST') c
                 on a.niu_lds = c.niu_lds

WHERE a.cod_eta_util in ('VER', 'APPR')
and a.id_cod_sr_alim = '2'
and b.cod_missn = 'PHA'
;

移除 AnalystFlag -

SELECT DISTINCT
    a.name_pers as "First Name",
    a.last_pers as "Last Name",
    a.id as "# account",
    a.cod_role_acces as "Profile", 
    a.niu_lds as "Company", 
    b.cod_missn as "Mission", 
    
FROM sr.c_r_v_obt_cp_util a 
  inner join ods.c_od_missn_ld b 
    on a.niu_lds = b.niu_lds
  left join (select distinct 1 as analyst, niu_lds
                 from sr.c_r_v_obt_cp_util
                 where cod_role_acces = 'ANALYST') c
                 on a.niu_lds = c.niu_lds

WHERE a.cod_eta_util in ('VER', 'APPR')
and a.id_cod_sr_alim = '2'
and b.cod_missn = 'PHA'
and c.analyst IS NULL
;

【讨论】:

  • 我似乎无法在我的代码中重现该示例。是否可以使用我提供的代码向我展示您的意思?
  • 我在编辑中添加了我认为在您的代码中等效的内容 - 如果第一个版本的公司缺少分析师标志,则可能是字符串问题,您可以尝试替换为“where cod_role_acces = 'ANALYST'" 用于 "where upper(cod_role_acces) LIKE '%ANALYST%'" 这应该可以减少空格和区分大小写的问题。
  • 我尝试了您的代码,但仍然无法正常工作。它还为我提供了有分析师的公司...非常感谢您的所有努力!
  • 当您在 Analyst 标志存在的情况下运行它时,cod_role_acces 在标记与不标记的方式中是否存在差异?有标记吗?您是否尝试将“where cod_role_acces = 'ANALYST'”替换为“where upper(cod_role_acces) LIKE '%ANALYST%'”?
  • 第一个在每列上给我“1”,第二个什么也没有。我得到几乎相同的结果。我可以在输出的任何地方看到“Analyst”..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 2021-07-29
  • 2020-03-05
相关资源
最近更新 更多