Как преобразовать этот подзапрос в объединение? - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть следующий запрос, который работает как ожидалось:

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

, но поскольку для каждой записанной записи может существовать несколько записей уведомлений, это дает больше результатов, чем при первой комбинации запроса / подзапроса.

Любая идея, как я могу это сделатьпоказывать записанные записи только один раз, если для него существует несколько записей уведомлений?

Ответы [ 4 ]

0 голосов
/ 27 ноября 2018
SELECT 
    insent.id, 
    notifications.id 
FROM insent 
JOIN (select distinct id, insent_id from notifications)notifications ON notifications.insent_id = insent.id
0 голосов
/ 27 ноября 2018

Джо Селко, автор SQL для Smarties, предлагает использовать предикат IN именно по этой причине.Вы не хотите использовать SELECT DISTINCT, потому что он использует внутренний курсор, который замедляет работу с большими наборами данных и способствует плохому дизайну.Вы буквально пытаетесь ограничить полученные результаты тем, какие идентификаторы существуют в другой таблице.Ваш первый запрос с использованием предиката IN является лучшим запросом.

0 голосов
/ 27 ноября 2018

Вы можете попробовать с 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
0 голосов
/ 27 ноября 2018

Просто используйте 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
)

ОДНАКО, неясно, как может работать первый запрос, который вы задаете в своем вопросе?Вы не можете получить доступ к атрибуту, вложенному в подзапрос конструкции IN из внешнего запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...