SQL clause select avec un composé
-
26-10-2019 - |
Question
J'ai deux tables de consultation / de référence (et non inscrits) Souscrits dans ma base de données Microsoft SQL Server 2008 avec la structure suivante:
UserId int
PublicationId int
Ces champs sont indexés ensemble comme un indice de composé.
Ce que je veux être en mesure de faire est de trouver tous les enregistrements qui existent dans le tableau désabonné qui ne dispose pas d'un enregistrement correspondant dans la table de Souscrit (correspondant à UserId et PublicationId)
Fonctionnellement, je veux quelque chose comme:
select PublicationId, UserId
from Unsubscribed
where PublicationId, UserId not in (
select PublicationId, UserId
from Subscribed
)
point Quelqu'un peut-moi dans la bonne direction?
Merci.
La solution
SELECT PublicationId, UserId
FROM Unsubscribed
MINUS
SELECT PublicationId, UserId
FROM Subscribed
Autres conseils
Vous pouvez utiliser un left join
pour trouver les publications non correspondants et les utilisateurs.
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
Ou si vous utilisez Microsoft SQL Server 2005/2008, vous pouvez alors utiliser le mot-clé Except
(utilisez le mot-clé Intersect
pour le contraire).
SELECT [PublicationId], [UserId]
FROM [Unsubscribed]
EXCEPT
SELECT [PublicationId], [UserId]
FROM [Subscribed]
Vous pouvez toujours convertir IN
à EXISTS
. Dans votre cas, cela ressemblerait à ceci:
select PublicationId, UserId
from Unsubscribed
where
not exists (
select *
from Subscribed
where Subscribed.PublicationId = Unsubscribed.PublicationId
and Subscribed.UserId = Unsubscribed.UserId
)
Par ailleurs, si vous utilisez Oracle, vous pouvez réellement mettre en œuvre directement votre intention initiale (ajouter seulement quelques parenthèses):
select PublicationId, UserId
from Unsubscribed
where (PublicationId, UserId) not in (
select PublicationId, UserId
from Subscribed
)
Vous pouvez utiliser un LEFT JOIN pour y parvenir;
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
Si vous êtes nouveau à se joindre à ce, Explication visuelle de Jeff Atwood est un bon endroit pour commencer.
En effet, ce que la requête est en train de faire est de ramener toutes les lignes de ubsubscribed qui ont une ligne correspondante dans Souscrit, et toutes les lignes de désabonné qui ont aucune ligne correspondant à souscrit - les lignes vous êtes abonné sont représentés avec de NULL pour ceux-ci.