Предложение выбора 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.

Другие вопросы по тегам