如果其他行中有 children,如何避免选择没有 child 的 parents 行?

How to avoid selection of rows of parents that don't have a child, if they have children in other rows?

我想避免选择存在空白 child 的情况,但只选择已经存在 parent-child 关系的情况。因此,在此示例中,A-D 将保留,但应删除带有 A 的空行。由于 C 在任何行中都没有任何 children,因此它将保留。

输入:

parent     child
A          D
A
A
B          E
B          F
C

期望的输出:

parent     child
A          D
B          E
B          F
C

我尝试过的:

SELECT parent, child
FROM my_table
WHERE child NOT NULL
EXCEPT 
SELECT parent, child
FROM my_table
-- condition to check existing relationships if they exist

您可以尝试将两个查询与 UNION ALL 一起使用,一个通过 child IS NOT NULL 获取结果,另一个通过条件聚合函数获取结果。

SELECT parent,child
FROM my_table
WHERE child IS NOT NULL
UNION ALL
SELECT parent,child
FROM my_table
GROUP BY parent,child
HAVING COUNT(CASE WHEN child IS NULL THEN 1 END) = 1

或者您可以在 HAVING 中使用另一种方法让条件变得简单。

SELECT parent,child
FROM my_table
GROUP BY parent,child
HAVING COUNT(CASE WHEN child IS NULL THEN 1 END) = 1 OR child IS NOT NULL 

也许使用如下查询。这使用 exists 关键字来检查是否存在任何其他非空子

SELECT parent, child
FROM my_table t
WHERE child is NOT NULL
OR NOT EXISTS 
(
SELECT 1 FROM my_table p Where p.parent=t.parent and p.child is Not null
)

这实际上是 2 个查询,所以我们可以用 UNION ALL

加入它们
  • 第一个查询是 child child is not null
  • 第二个查询是children的个数为0。默认情况下COUNT()不包含空值。我们还使用 GROUP BY,这意味着将合并重复的行。
SELECT parent, child FROM t
WHERE child IS NOT NULL
UNION ALL
SELECT parent, null FROM t
GROUP BY parent
HAVING COUNT(child) = 0;
parent | child
:----- | :----
A      | D    
B      | E    
B      | F    
C      | null 

db<>fiddle here