在SQL查询中根据子项的匹配值获取父项值

时间:2019-12-11 07:23:12

标签: sql oracle

我需要选择查询中的父表值,其中父表的子值中有几个或全部都在子表中。

让我给你举个例子。

类别父表

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值。

编辑:我们可以在不使用分组和计数的情况下实现这一目标吗?

3 个答案:

答案 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 BYHAVING

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 existgroup by + having count来模拟它。

This is IMHO the best article on this topic.,您可以轻松地从中学习如何将两种方式应用于示例。