我有一个包含两个表的场景
Table1 (ID INT, Name VARCHAR)
Values(1, 'A')
Values(2,'B')
Values(3,'C')
Table2 (Val VARCHAR(4), Name VARCHAR)
Values('V01','A')
Value('V02' , 'A')
Value('V01', 'B')
Value('V04' , 'B')
Value('V03', 'B')
Value('V02' , 'C')
NAME列是主要的IN表1,在表2中引用
我想在输出中使用ID和NAME,这样只有来自Table1的Name才会出现具有值' V01'和' V02'在表2中
输出应该是
ID | Name
1 | A
请建议使用分析函数和/或不使用公用表表达式(CTE)的解决方案
我找到的一个解决方案是
WITH CTE AS (SELECT *, CASE VAL WHEN 'V01' THEN 0 WHEN 'V02' THEN 0 ELSE 1 END AS CAS FROM table2) SELECT t1.ID, t1.NAME FROM table1 t1 JOIN (SELECT NAME,SUM(CAS) AS "SumC" FROM CTE GROUP BY NAME) AS "NewT" ON t1.NAME = NewT.NAME WHERE NewT.SumC =0
答案 0 :(得分:0)
您不需要CTE或分析功能,您可以使用聚合:
select t1.id, t1.name
from table1 t1
join table2 t2 on t2.name = t1.name
where t2.val in ('V01', 'V02')
group by t1.id, t1.name
having count(t2.val) = 2;
ID N
---------- -
1 A
如果可能有多个匹配,那么条件可以是:
having count(distinct t2.val) = 2;
这会加入表格,只查找您感兴趣的两个值;然后计算它实际匹配的那些值的可能性。您想要两者,因此计数必须与您要查找的值的数量相匹配。
您还可以为要查找的每个值使用单独的exists
子句,逻辑可能更直观:
select t1.id, t1.name
from table1 t1
where exists (
select null
from table2 t2
where t2.name = t1.name
and t2.val = 'V01'
)
and exists (
select null
from table2 t2
where t2.name = t1.name
and t2.val = 'V02'
);
但是这会多次击中第二个表,并且在术语或性能或代码可读性/维护方面无法很好地扩展。