SQL查询以查找仅具有一行的行(用于exp许可证)

时间:2018-10-04 20:22:54

标签: sql oracle

我有一个查询,它从多个表中提取数据,包括一个名为empl_access的表。我只需要s_system_cd类型为WEC的在职员工。

此字段有两个值:WECWTC。员工可以同时拥有两个,但是我希望只有WEC一个的员工。

到目前为止,这是我的脚本。这会拉出所有WEC行,但其中一些行也有WTC,我希望将它们过滤掉。

select DISTINCT a.empl_id, a.last_name, a.first_name, a.active_fl,    
   b.UDT09_ABBRV_ID, c.s_system_cd, count(a.empl_id) over ()
from empl a, V_TBE_MAX_EMPL_HISTORY b, empl_access c 
where a.empl_id=b.empl_id 
   and a.empl_id=c.empl_id
   and a.active_fl='Y'
   and c.s_system_cd like 'WEC%'
order by a.empl_id;

这是表格中的示例:

empl_id    | last_name      | first_name     | udt09_abbr_id       | s_system_cd
-----------|----------------|----------------|---------------------|-----------------
000000     | Mouse          | Mickey         | 1111                | WEC
-----------|----------------|----------------|---------------------|-----------------
000000     | Mouse          | Mickey         | 1111                | WTC
-----------|----------------|----------------|---------------------|-----------------
000010     | Duck           | Donald         | 1111                | WEC
-----------|----------------|----------------|---------------------|-----------------
000010     | Duck           | Donald         | 1111                | WTC
-----------|----------------|----------------|---------------------|-----------------
000020     | Parker         | John           | 1150                | WEC
-----------|----------------|----------------|---------------------|-----------------
000030     | Smith          | Anne           | 1152                | WEC

这就是我要拉的

-----------|----------------|----------------|---------------------|-----------------
empl_id    | last_name      | first_name     | udt09_abbr_id       | s_system_cd
-----------|----------------|----------------|---------------------|-----------------
000020     | Parker         | John           | 1150                | WEC
-----------|----------------|----------------|---------------------|-----------------
000030     | Smith          | Anne           | 1152                | WEC
-----------|----------------|----------------|---------------------|-----------------

2 个答案:

答案 0 :(得分:3)

这样的帮助吗?

SQL> with test (empl_id, s_system_cd) as
  2    (select 1, 'WEC' from dual union all  -- EMPL_ID = 1 has both - we don't want it
  3     select 1, 'WTC' from dual union all
  4     select 2, 'WTC' from dual union all  -- EMPL_ID = 2 has only WTC - we don't want it
  5     select 3, 'WEC' from dual union all  -- EMPL_ID = 3 has only WEC - we do want it
  6     select 4, 'WEC' from dual union all  -- EMPL_ID = 4 has WEC, twice - we do want it
  7     select 4, 'WEC' from dual
  8    )
  9  select empl_id
 10  from test
 11  group by empl_id
 12  having min(s_system_cd) = max(s_system_cd)
 13     and min(s_system_cd) = 'WEC'
 14  order by empl_id;

   EMPL_ID
----------
         3
         4

SQL>

答案 1 :(得分:0)

SELECT DISTINCT a.empl_id, a.last_name, a.first_name, a.active_fl,    
   b.UDT09_ABBRV_ID, c.s_system_cd, count(a.empl_id) over ()
FROM empl a
INNER JOIN V_TBE_MAX_EMPL_HISTORY b ON a.empl_id=b.empl_id 
INNER JOIN empl_access c ON a.empl_id=c.empl_id AND c.s_system_cd like 'WEC%'
LEFT JOIN empl_access c2 ON a.empl_id=c2.empl_id AND c2.s_system_cd like 'WTC%'
WHERE a.active_fl='Y' AND c2.empl_id IS NULL
ORDER BY a.empl_id;

您也可以使用EXISTS操作或GROUP BY以及聚合函数的一些花哨的技巧(其他答案中的min = max起作用;检查count = 1也可以)和max ='WEC')。

此答案中的示例是您应该始终 * 编写联接的方式。

empl a, V_TBE_MAX_EMPL_HISTORY b, empl_access c的东西是给鸟的。随着您添加更多表或条件,阅读和管理变得越来越困难,某些事情旧的语法无法做到,并且大约20年以来,旧的语法已被认为已经过时。


*我不经常使用Oracle,但我知道在极少数情况下可能需要使用较旧的语法。但是除此之外(您会知道是否找到它),坚持写出INNERLEFTCROSSFULLLATERAL等等