SQL:如何将重复行与唯一行相关联并将它们从另一个 table 中删除?

SQL: How to relate duplicate rows to unique rows and remove them from another table?

目前我有两个表Table_ATable_B

Table_A

ID

1
2
2
3
3
4

Table_B

ID   Alphabet
1       X
1       Y
2       X
2       Y
2       Z
3       X
3       Z
4       X

我想对 Table_B 中的列 ID 和字母表进行分组,并找出组合中的哪一组包含字母表 Z。

那么无论哪个组里有Z,我查Table_A的ID都不会显示它的ID。

预期结果

ID 
1
4

我目前正在使用这个 SELECT 语句:

SELECT A.ID FROM Table_A A LEFT JOIN Table_B B 
ON A.ID = B.ID WHERE A.ID NOT IN (SELECT B.ID FROM Table_B 
WHERE Alphabet = 'Z' GROUP BY B.ID, Alphabet)

实际结果

ID 
1
1
2
2
3
4

它删除了其中包含字母 Z 但与其他重复 ID 无关的 ID。

使用此连接创建组字母表

How can I combine multiple rows into a comma-delimited list in Oracle?

那么你将拥有

   id    alphabet
   1     x,y
   2     x,y,z
   3     x,z
   4     x

然后

SELECT id
FROM newQuery
WHERE INSTR(LOWER(alphabet), 'z') = 0;

这个怎么样:

select id 
from table_a
where not exists (
  select 1 from table_b 
  where table_b.id = table_a.id 
  and table_b.alphabet = 'Z')

如果您使用的是 oracle,则可以使用 LISTAGG 函数使用逗号连接值。您可以参考以下代码:

SELECT 
                    id ,
                    LISTAGG((alphabet)|| ',' ORDER BY id)  (VARCHAR(1000))  alphabet_list
            from 
            table
            group by 
                    id   
            ;

然后使用 INSTR 删除具有 Z 的记录。

您希望每个 ID 一条记录,因此您按 ID 分组。然后您需要有关 ID 数据的信息并相应地限制您的结果,因此您使用 HAVING 子句。计算每个ID的Zs,只保留找到的Zs数量为0的ID。

select id
from table2
group by id
having count(case when alphabet = 'Z' then 1 end) = 0;

顺便说一句,这只是一个替代方案。如 Frank Ockenfuss 所示,直接的方法是 NOT EXISTS(或 NOT IN)。我的解决方案的优点是您只需阅读一个 table,但缺点是只显示 table2 中存在的 ID。所以你看到有其他选择,但你最好在这里接受 Frank 的回答 :-) 我写这篇文章是因为我看到你正在尝试自己用 GROUP BY 做一些事情。