如何从表中返回特定值

时间:2018-02-23 11:33:12

标签: sql oracle join subquery

我需要从表中返回行,其中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 IDCode列中只有B。但是,它存在于表B中,因此我不想在输出中返回此行。

4 个答案:

答案 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