我需要从表中返回行,其中ID
的所有行都具有CODE
的某些特定值。
例如:
TABLE: A
ID | NAME |CODE
-----------------
101 | XXX | A
101 | XXX | B
101 | XXX | C
101 | XXX | A
102 | XXX | B
103 | XXX | B
104 | XXX | D
104 | XXX | B
105 | XXX | A
105 | XXX | B
105 | XXX | D
105 | XXX | A
106 | XXX | B
107 | XXX | B
我需要只有代码B
的行。所以这是上表的预期输出:
ID | NAME |CODE
-----------------
102 | XXX | B
103 | XXX | B
106 | XXX | B
107 | XXX | B
此处ID
101,104,105也有代码B,但它们不应该在我的输出中返回,因为它们还有其他代码。
我可以编写什么查询来获得输出?
我还需要确保在另一个表B中不存在这些值。所以,我需要添加
AND NOT EXISTS (SELECT 1 FROM TABLE B WHERE B.ID = A.ID)
B表有主键ID
,B表中没有Code列。我只是使用这个表来消除公共ID,因为我需要表A中存在的结果,而不是表B.
以下是
中的示例数据Table : B
ID | Name | City | Department
------------------------------
101 | XXX | XXX | XX
104 | XXX | XXX | XX
105 | XXX | XXX | XX
107 | XXX | XXX | XX
表A中的,107 ID
在Code
列中只有B。但是,它存在于表B中,因此我不想在输出中返回此行。
答案 0 :(得分:0)
这是一种方法:
select b.id
from tableb b
group by b.id
having min(b.code) = max(b.code) and min(b.code) = 'B';
如果您具体指的是没有" A"和" B",但允许其他代码,然后你可以这样做:
select b.id
from tableb b
where b.code in ('A', 'B')
group by b.id
having min(b.code) = max(b.code) and min(b.code) = 'B';
答案 1 :(得分:0)
又一个选择:
select id
from tableb
group by id
having sum(decode(code, 'B', 0, 1)) = 0
[修改问题后修改]
select *
from tablea a
where a.id in (select a1.id
from tablea a1
group by a1.id
having sum(decode(a1.code, 'b', 0, 1)) = 0
)
and not exists (select null from tableb b where b.id = a.id)
答案 2 :(得分:0)
以下是使用NOT EXISTS
的解决方案:
SELECT
ID
,NAME
,CODE
FROM tblA a
WHERE CODE = 'B'
AND NOT EXISTS (
SELECT ID
FROM tblA b
WHERE CODE <> 'B'
AND a.ID = b.ID
)
AND NOT EXISTS (
SELECT ID
FROM tblB c
WHERE a.ID = c.ID
)
答案 3 :(得分:0)
每当您需要像count
这样的分组功能时,您希望保留所有细节,请使用分析功能。甲骨文说:
它们与聚合函数的不同之处在于它们返回多行 对于每个小组。
这样可以避免两次击中表格。还要小心正确处理nulls
。
select id, name
from (select id, name, code,
count(case when code <> 'B' or code is null then 1 end)
over (partition by id) cnt
from a) a
where cnt = 0 and not exists (select 1 from b where id = a.id)
<强> SQL demo 强>