我有一个查询,它从多个表中提取数据,包括一个名为empl_access
的表。我只需要s_system_cd
类型为WEC
的在职员工。
此字段有两个值:WEC
和WTC
。员工可以同时拥有两个,但是我希望只有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 -----------|----------------|----------------|---------------------|-----------------
答案 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,但我知道在极少数情况下可能需要使用较旧的语法。但是除此之外(您会知道是否找到它),坚持写出INNER
,LEFT
,CROSS
,FULL
,LATERAL
等等