SQL SELECT clausola con un composto
-
26-10-2019 - |
Domanda
Ho due tabelle di ricerca / di riferimento (sottoscritto e non sottoscritti) nel mio database Microsoft SQL Server 2008 con la seguente struttura:
UserId int
PublicationId int
Questi campi sono indicizzati insieme come un indice composto.
Quello che voglio essere in grado di fare è trovare tutti i record presenti nella tabella Unsubscribed che non hanno un record corrispondente nella tabella iscrizioni (corrispondenti UserID e PublicationId)
punto di vista funzionale, voglio qualcosa di simile:
select PublicationId, UserId
from Unsubscribed
where PublicationId, UserId not in (
select PublicationId, UserId
from Subscribed
)
Qualcuno può punto nella giusta direzione me?
Grazie.
Soluzione
SELECT PublicationId, UserId
FROM Unsubscribed
MINUS
SELECT PublicationId, UserId
FROM Subscribed
Altri suggerimenti
È possibile utilizzare un left join
per trovare le pubblicazioni non corrispondenza e degli utenti.
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
Se si utilizza Microsoft SQL Server 2005/2008, è possibile utilizzare la parola chiave Except
(utilizzare la parola chiave Intersect
per il contrario).
SELECT [PublicationId], [UserId]
FROM [Unsubscribed]
EXCEPT
SELECT [PublicationId], [UserId]
FROM [Subscribed]
È sempre possibile convertire i IN
a EXISTS
. Nel tuo caso, questo sarebbe simile a questa:
select PublicationId, UserId
from Unsubscribed
where
not exists (
select *
from Subscribed
where Subscribed.PublicationId = Unsubscribed.PublicationId
and Subscribed.UserId = Unsubscribed.UserId
)
Per inciso, se si utilizza Oracle, si può effettivamente implementare l'originale intento direttamente (è sufficiente aggiungere un paio di parentesi):
select PublicationId, UserId
from Unsubscribed
where (PublicationId, UserId) not in (
select PublicationId, UserId
from Subscribed
)
È possibile utilizzare un LEFT JOIN per raggiungere questo obiettivo;
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
Se siete nuovi a unirsi di, Jeff Atwood visiva Spiegazione è un buon posto per iniziare.
In effetti, ciò che la query sta facendo è riportare tutte le righe in ubsubscribed che hanno una riga corrispondente nella sottoscritto, e tutte le righe in Unsubscribed che non hanno righe corrispondenti nella sottoscritto - le righe sottoscritto sono rappresentati con NULL per questi.