如何将这个子查询转换成连接?

yruzcnhs  于 2021-06-17  发布在  Mysql
关注(0)|答案(4)|浏览(244)

我得到了以下查询,它按预期工作:

SELECT insent.id, notifications.id
FROM insent
WHERE insent.id IN (
    SELECT insent_id
    FROM notifications
);

这和预期的一样,但我想将其转换为带有连接的查询。我可以做到:

SELECT 
    insent.id, 
    notifications.id 
FROM insent 
JOIN notifications ON notifications.insent_id = insent.id

但是,由于每个insent记录都可以存在多个通知记录,因此这会产生比第一个查询/子查询组合更多的结果。
如果存在多个通知记录,我怎么只能显示一次插入的记录?

qq24tv8q

qq24tv8q1#

只是使用 distinct 避免 insent 复制品

SELECT distinct
    insent.id
FROM insent 
JOIN notifications ON notifications.insent_id = insent.id

我相信使用 IN 好多了。查询优化器很可能使用这样的半连接。

SELECT insent.id
FROM insent
WHERE insent.id IN (
    SELECT insent_id
    FROM notifications
)

但是,不清楚您在问题中提供的第一个查询如何工作?不能从外部查询访问嵌套在构造内子查询中的属性。

ui7jx7zq

ui7jx7zq2#

SELECT 
    insent.id, 
    notifications.id 
FROM insent 
JOIN (select distinct id, insent_id from notifications)notifications ON notifications.insent_id = insent.id
euoag5mw

euoag5mw3#

sql for smarties的作者joe celko建议使用in predicate 正是出于这个原因。您不希望使用selectdistinct,因为它使用了一个内部游标,这会减慢较大数据集上的速度,并会导致糟糕的设计。实际上,您正试图通过另一个表中存在的标识符来限制插入结果。第一个查询,使用in predicate 是更好的查询。

6xfqseft

6xfqseft4#

你可以试试 ROW_NUMBER ```
SELECT r.NotificationId,InsentId
FROM ( SELECT
insent.id AS InsentId,
notifications.id AS NotificationId,
ROW_NUMBER () OVER ( PARTITION BY i.id ORDER BY i.Id ) AS rn
FROM insent i
JOIN notifications n ON n.insent_id = i.id ) as r
WHERE rn=1

相关问题