Come interrogare e ottenere un set di risultati contenente almeno il SET di valori inviati
WITH fData AS
(
SELECT 1001 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'B' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'C' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'D' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'S' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'J' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'H' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'I' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'C' AS LookUpValue
)
SELECT *
FROM fData fd
WHERE fd.LookUpValue IN ('A','B','C','D') /* This pulls back ANY record having these values and then return all of the records in that list. I want ONLY lists that have a minimum of these values. For example of my list only contained 'A' I would see both List 1001 records and List 1002 Records. */
;
Il codice che ho fornito contiene semplicemente tre elenchi falsi. Ciascun elenco contiene un insieme di valori. Come scrivo una query che mi fornisce tutti i record nell'elenco che contengono i valori specificati. L'utilizzo di un'istruzione IN non funziona in quanto mi fornisce TUTTI gli elenchi (record) che contengono quei valori di elenco. Invece ho bisogno di restituire solo i record dell'elenco che contengono almeno tutti i valori che ho specificato.
Nel mio esempio, poiché ho fornito quattro valori ("A", "B", "C", "D"), dovrei vedere solo nel set di risultati i record per il primo elenco con lookupID 1001. Se ad esempio invio un singolo valore di "A", vedrei quindi tutti i record per List 1001 e List 1002 poiché entrambi gli elenchi contengono almeno il valore "A". L'elenco 1003 non ha alcun valore di "A".
Risposte
Ottieni lookupID
i messaggi che desideri con questa query:
SELECT lookupID
FROM fData
WHERE LookUpValue IN ('A','B','C','D')
GROUP BY lookupID
HAVING COUNT(DISTINCT LookUpValue) = 4 -- the number of searched lookupvalues
e tutte le righe della tabella con l'utilizzo dell'operatore IN
:
SELECT * FROM fData
WHERE lookupID IN (
SELECT lookupID
FROM fData
WHERE LookUpValue IN ('A','B','C','D')
GROUP BY lookupID
HAVING COUNT(DISTINCT LookUpValue) = 4
)
Il codice è SQL standard e funziona in qualsiasi database (che io conosca).
Guarda la demo .
Risultati:
> lookupID | LookUpValue
> -------: | :----------
> 1001 | A
> 1001 | B
> 1001 | C
> 1001 | D
Una variante della query forpas che utilizza aggregati in finestra invece di raggruppare per
WITH fData AS
(
SELECT 1001 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'B' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'C' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'D' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'E' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'S' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'J' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'H' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'I' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'C' AS LookUpValue
),
cte as
(
SELECT *,
count(case when LookUpValue IN ('A','B','C','D') then 1 end)
over (partition by lookupID) as cnt
FROM fData
)
select lookupID, LookUpValue
from cte
where cnt = 4
Funziona solo se la combinazione lookupID | LookUpValue è unica (questo semplificherebbe anche la query forpas eliminando DISTINCT).
Vedi violino