Pergunta

I have two lookup/reference tables (Subscribed and Unsubscribed) in my Microsoft SQL Server 2008 database with the following structure:

UserId int
PublicationId int

These fields are indexed together as a compound index.

What I want to be able to do is find all of the records that exist in the Unsubscribed table that do not have a matching record in the Subscribed table (matching UserId and PublicationId)

Functionally, I want something like:

select PublicationId, UserId
from Unsubscribed
where PublicationId, UserId not in (
   select PublicationId, UserId
   from Subscribed
)

Can anyone point me in the right direction?

Thanks.

Foi útil?

Solução

SELECT PublicationId, UserId
FROM   Unsubscribed
MINUS
SELECT PublicationId, UserId
FROM   Subscribed

Outras dicas

You can use a left join to find the non matching publications and users.

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

Or if you are using Microsoft SQL Server 2005 / 2008 then you can use the Except keyword (use the Intersect keyword for the opposite).

SELECT [PublicationId], [UserId]
FROM [Unsubscribed] 

EXCEPT

SELECT [PublicationId], [UserId]
FROM [Subscribed]

You can always convert IN to EXISTS. In your case, this would look like this:

select PublicationId, UserId
from Unsubscribed
where
   not exists (
      select *
      from Subscribed
      where Subscribed.PublicationId = Unsubscribed.PublicationId
         and Subscribed.UserId = Unsubscribed.UserId
   )

Incidentally, if you are using Oracle, you can actually implement your original intent directly (just add a couple of parenthesis):

select PublicationId, UserId
from Unsubscribed
where (PublicationId, UserId) not in (
   select PublicationId, UserId
   from Subscribed
)

You can use a LEFT JOIN to achieve this;

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

If you are new to join's, Jeff Atwood's Visual Explanation is a good place to start.

Effectively, what the query is doing is bringing back all of the rows in ubsubscribed that have a matching row in Subscribed, and all of the rows in Unsubscribed that have no matching rows in subscribed - the rows in subscribed are represented with NULL's for these.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top