查询根据列值从引用表中提取数据

时间:2018-01-11 10:59:41

标签: sql oracle

我有一个包含两个表的场景 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

1 个答案:

答案 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'
);

但是这会多次击中第二个表,并且在术语或性能或代码可读性/维护方面无法很好地扩展。