我有三个表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
答案 0 :(得分:2)
我将使用listagg
将所有代码连接成一个字符串(agregated_codes
),然后检查匹配(最终选择语句)。但在此之前,我只会从Bdata
(distinct_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
。