我确信有一个简单的解决方案可以解决我想要做的事情,但我无法通过它来思考。
表A - 列 - ITEMNUM - ITEMNAME
1 Test1
2 Test2
3 Test3
4 Test4
5 Test5
6 Test6
表B - 列 - ITEMNUM CHAR
1 A
1 B
2 A
2 C
3 A
3 D
4 A
4 E
5 A
5 F
6 A
6 F
我想做的是
select itemname
from A, b
where a.itemnum = b.itemnum
然后我只想要char =' A'但是当B,C或D也有相同的itemnum时。 itemnum必须有一个char是' A'然后它可能是具有相同itemnum的其他东西,但它不能是B,C或D.并非所有itemnum都会有一个值为' A'的char。希望这是有道理的。
Test4,Test5和Test6应该是唯一返回的。
我必须将此代码放入另一个不允许我使用pl / sql的程序中。
建议?
答案 0 :(得分:1)
在B上使用NOT EXISTS
进行自我联接select itemname
from A, b
where a.itemnum = b.itemnum
and not exists( select 1 from b2 where b2.itemnum = b.itemnum and b2.char in ('B', 'C', 'D'));
您可能也想开始使用ANSI连接语法:
select itemname
from A
join b on a.itemnum = b.itemnum
where not exists( select 1 from b2 where b2.itemnum = b.itemnum and b2.char in ('B', 'C', 'D'));
答案 1 :(得分:1)
这样的事情应该有效
SELECT a.itemname
FROM a
WHERE EXISTS (
SELECT 1
FROM b
WHERE b.itemnum = a.itemnum
AND b.char = 'A'
)
AND NOT EXISTS (
SELECT 1
FROM b
WHERE b.itemnum = a.itemnum
AND b.char IN ('B', 'C', 'D')
)
编辑:不确定这是否是您想要的(请分享预期的结果结构和数据,例如您对表A和B所做的那样),但这可能是第二步:
SELECT a.itemname, b.char
FROM a
INNER JOIN b
ON b.itemnum = a.itemnum
WHERE EXISTS (
SELECT 1
FROM b b_char
WHERE b_char.itemnum = a.itemnum
AND b_char.char = 'A'
)
AND NOT EXISTS (
SELECT 1
FROM b b_char
WHERE b_char.itemnum = a.itemnum
AND b_char.char IN ('B', 'C', 'D')
)
编辑2:请查看此SQL Fiddle,了解其工作原理。
结果基本上是:
ITEMNAME | CHAR ---------+----- Test4 | A Test4 | E Test5 | A Test5 | F Test6 | A Test6 | F
答案 2 :(得分:1)
您可以使用listagg
构建一个包含每个itemname所有字符的字符串。然后,您可以过滤A
但没有B
,C
或D
的行:
with list as
(
select ITEMNAME
, listagg("CHAR") within group (order by "CHAR") chars
from TableA a
join TableB b
on a.ITEMNUM = b.ITEMNUM
group by
ITEMNAME
)
select *
from list
where chars like '%A%'
and not regexp_like(chars, '[BCD]')
答案 3 :(得分:0)
select itemnum from (
select a.itemnum,
max(case when b.char in ('B','C','D') then 'Y' else 'N' end) bad_check,
max(case when b.char = 'A' then 'Y' else 'N' end) has_an_a
from A, b
where a.itemnum = b.itemnum
group by a.itemnum
) where has_an_a='Y'
and bad_check='N';