Предложение выбора SQL с составным
У меня есть две справочные таблицы (подписанные и неподписанные) в моей базе данных Microsoft SQL Server 2008 со следующей структурой:
UserId int
PublicationId int
Эти поля индексируются как составной индекс.
То, что я хочу сделать, это найти все записи, которые существуют в таблице Unsubscribeed, у которых нет соответствующей записи в таблице Subscribeed (совпадающей UserId и PublicationId)
Функционально я хочу что-то вроде:
select PublicationId, UserId
from Unsubscribed
where PublicationId, UserId not in (
select PublicationId, UserId
from Subscribed
)
Может кто-то указать мне верное направление?
Благодарю.
4 ответа
SELECT PublicationId, UserId
FROM Unsubscribed
MINUS
SELECT PublicationId, UserId
FROM Subscribed
Вы можете использовать left join
найти несоответствующие публикации и пользователей.
SELECT U.[PublicationId], U.[UserId]
FROM [Unsubscribed] AS U
LEFT JOIN [Subscribed] AS S ON S.[PublicationId] = U.[PublicationId]
AND S.[UserId] = U.[UserId]
WHERE S.[PublicationId] IS NULL
AND S.[UserId] IS NULL
Или, если вы используете Microsoft SQL Server 2005 / 2008, вы можете использовать Except
ключевое слово (используйте Intersect
Ключевое слово для противоположности).
SELECT [PublicationId], [UserId]
FROM [Unsubscribed]
EXCEPT
SELECT [PublicationId], [UserId]
FROM [Subscribed]
Вы всегда можете конвертировать IN
в EXISTS
, В вашем случае это будет выглядеть так:
select PublicationId, UserId
from Unsubscribed
where
not exists (
select *
from Subscribed
where Subscribed.PublicationId = Unsubscribed.PublicationId
and Subscribed.UserId = Unsubscribed.UserId
)
Кстати, если вы используете Oracle, вы можете напрямую реализовать свое первоначальное намерение (просто добавьте пару круглых скобок):
select PublicationId, UserId
from Unsubscribed
where (PublicationId, UserId) not in (
select PublicationId, UserId
from Subscribed
)
Вы можете использовать левое соединение для достижения этого;
SELECT U.*, S.PublicationId
FROM Unsubscribed U
LEFT JOIN Subscribed S ON U.PublicationId = S.PublicationId AND U.UserId = S.UserId
WHERE S.PublicationId IS NULL
Если вы новичок в присоединении, визуальное объяснение Джеффа Этвуда - хорошее место для начала.
По сути, запрос выполняет возвращение всех строк в подписке, которые имеют совпадающую строку в подписке, и все строки в подписке, которые не имеют совпадающих строк в подписке - строки в подписке для них обозначены как NULL.