如何获得具有where子句的所有值的表条件的结果

时间:2016-09-08 07:20:42

标签: sql oracle

我有三个表A和B和C,A的主键存在于B中,C的主键存在于B中: 表A:

id
---
1
2
3
4

表B:

id   A_id     code      c_id  
-----------------------------
1     1        20        1
2     1        30        1
3     1        40        3
4     2        20        2
5     3        30        3
6     4        40        2
7     4        30        2
8     1        20        3
9     4        30        4

表C:

 id   name
    ---------
    1
    2
    3
    4

我有一个查询,它有一个where子句,由B的列代码值和A
的返回记录组成 我想获得A的记录,那些具有where子句的总代码而不是其中一些。
例如:

SELECT ID FROM A a INNER JOIN B b
            ON a.id = b.A_id
    where b.code in(20, 30, 40);

我的期望值仅低于A:

的结果
id
----
1

因为最高结果(" 1")只有代码的所有值(20,30,40) 另一个例子是:

SELECT ID FROM A a INNER JOIN B b
            ON a.id = b.A_id
    where b.code in(30, 40);

我的期望是:

id
----
4

4 个答案:

答案 0 :(得分:2)

我将使用listagg将所有代码连接成一个字符串(agregated_codes),然后检查匹配(最终选择语句)。但在此之前,我只会从Bdatadistinct_data

收集不同的记录
with
Adata as (
select 1 id from dual union all
select 2 id from dual union all
select 3 id from dual union all
select 4 id from dual 
),
 Bdata as (
select 1 id,     1 a_id,        20 code,        1 c_id from dual union all
select 2 id,     1 a_id,        30 code,        1 c_id from dual union all
select 3 id,     1 a_id,        40 code,        3 c_id from dual union all
select 4 id,     2 a_id,        20 code,        2 c_id from dual union all
select 5 id,     3 a_id,        30 code,        3 c_id from dual union all
select 6 id,     4 a_id,        40 code,        2 c_id from dual union all
select 7 id,     4 a_id,        30 code,        2 c_id from dual union all
select 8 id,     1 a_id,        20 code,        3 c_id from dual union all
select 9 id,     4 a_id,        30 code,        4 c_id from dual
),
distinct_data as
(
select distinct a_id,code from Bdata 
),
agregated_codes as 
(
select a_id, listagg(code,',') within group (order by a_id) codes    
from distinct_data  group by a_id 
)
select * from Adata where id in ( select a_id from agregated_codes where codes in ('20,30,40'))

<强>结果:

'20,30,40'结果的

1

'30,40'结果的

4

答案 1 :(得分:0)

您可以尝试这样:

Select A.Id
from A a INNER JOIN B b
        ON a.id = b.A_id
where b.code in(20, 30, 40)
group by A.Id
having count(A.Id) = 3

此处最后一行count(A.Id) = 3将确保在满足IN子句中指定的所有代码时返回Id。

修改

试试这个:

SELECT DISTINCT (A.Id) 
FROM A a INNER JOIN B b
            ON a.id = b.A_id
WHERE A.Id In (select A_id from user where code = 20) 
    And A.Id In (select A_id from user where code = 30)  
    And A.Id In (select A_id from user where code = 40) ;

答案 2 :(得分:0)

使用exists子句。

仅选择代码值为20,30和40的记录。

select distinct a_id from B outB
where exists (select code from B  where outB.a_id = a_id and code =20)
and exists (select * from B where outB.a_id = a_id and code =30)
and exists (select * from B where outB.a_id = a_id and code =40);

仅选择那些代码值为30和40的记录。

select distinct a_id from B outB
where not exists (select * from B where outB.a_id = a_id and code =20)
and exists (select * from B where outB.a_id = a_id and code =30)
and exists (select * from B where outB.a_id = a_id and code =40);

答案 3 :(得分:0)

您可以为每个B.code值收集单列中的所有B.A_id值,然后只需将此列与'10,20,30'等条件字符串进行比较。

SELECT t.A_id 
  FROM ( SELECT t_B.A_id, LISTAGG(t_B.code, ',')  WITHIN GROUP (ORDER BY t_B.code) AS all_codes FROM (SELECT DISTINCT B.A_id, B.code FROM B) t_B  GROUP BY t_B.A_id) t
 WHERE t.all_codes LIKE '30,40'

我已更正了我的代码,添加了DISTINCT