我需要选择查询中的父表值,其中父表的子值中有几个或全部都在子表中。
让我给你举个例子。
类别父表
CatId PrdId
-----------
Cat1 prd1
Cat1 prd2
Cat1 prd3
Cat2 prd4
Cat2 prd5
Cat2 prd6
产品子表
PrdId
-----
prd1
prd2
prd3
prd4
prd5
我正在使用oracle sqldevloper。参见下面的查询,
Select Category.CatId
from Category cat
left join Product prd ON cat.PrdId = prd.PrdId
此查询为我提供Cat1,Cat2结果,但它应该仅获得Cat1,因为Product表中没有Cat2 prd6值。
编辑:我们可以在不使用分组和计数的情况下实现这一目标吗?
答案 0 :(得分:1)
该解决方案如何?
select distinct catid from category where catid not in (
select distinct c.catid from category c left join product p on (c.prdid = p.prdid) where p.prdid is null);
您基本上选择了所有产品并为它们分配了相关类别。那些没有类别的分配为NULL。然后,您仅选择具有NULL的那些类别,然后从包含所有类别的另一个选择中删除此类类别列表。
答案 1 :(得分:1)
您可以按以下方式使用GROUP BY
和HAVING
:
SQL> WITH CATEGORY AS ( 2 SELECT 'Cat1' CATID, 'prd1' PRDID FROM DUAL UNION ALL 3 SELECT 'Cat1' CATID, 'prd2' PRDID FROM DUAL UNION ALL 4 SELECT 'Cat1' CATID, 'prd3' PRDID FROM DUAL UNION ALL 5 SELECT 'Cat2' CATID, 'prd4' PRDID FROM DUAL UNION ALL 6 SELECT 'Cat2' CATID, 'prd5' PRDID FROM DUAL UNION ALL 7 SELECT 'Cat2' CATID, 'prd6' PRDID FROM DUAL 8 ), PRODUCT AS ( 9 SELECT 'prd1' PRDID FROM DUAL UNION ALL 10 SELECT 'prd2' PRDID FROM DUAL UNION ALL 11 SELECT 'prd3' PRDID FROM DUAL UNION ALL 12 SELECT 'prd4' PRDID FROM DUAL UNION ALL 13 SELECT 'prd5' PRDID FROM DUAL 14 ) -- Your actual solution starts from here 15 SELECT CAT.CATID 16 FROM CATEGORY CAT LEFT JOIN PRODUCT P ON CAT.PRDID = P.PRDID 17 GROUP BY CAT.CATID 18 HAVING COUNT(CASE WHEN P.PRDID IS NULL THEN 1 END) = 0; CATI ---- Cat1 SQL>
干杯!
答案 2 :(得分:0)
您要寻找的被称为 relational division 。它是基于关系代数的运算,在某种程度上可以视为笛卡尔乘积的逆。不幸的是,它在SQL标准中没有直接支持。您可以用两个not exist
或group by + having count
来模拟它。
This is IMHO the best article on this topic.,您可以轻松地从中学习如何将两种方式应用于示例。