2016-09-23 5 views
1

I eine Tabelle wie so haben:Abrufen alle unterschiedlichen Werte in einer Spalte, die in anderen Spalte (SQL) Kombination aus Bedingung erfüllt

+-----------------+-----------------+ 
+  x  +  y  + 
+-----------------+-----------------+ 
+  a  +  1  + 
+  a  +  2  + 
+  b  +  1  + 
+  b  +  3  + 
+  c  +  1  + 
+  c  +  2  + 
+  c  +  3  + 
+-----------------+-----------------+ 

Say ich alle unterschiedlichen Zeilen in x finden wollen, dass eine gewünschte enthalten Kombination von Werten in y pro Gruppe.

Angenommen, die Bedingung ist, alle Gruppen zu finden, in denen y = [1,2]. Dies würde a und c ergeben.

Beachten Sie, dass die Lösung auf eine beliebige Anzahl von Kombinationen in y skaliert werden muss, z. B. , was c ergeben würde.

+0

welche RDBMS werden Sie verwenden, SQL servery? MySql? – EoinS

+0

@EoinS PostgreSQL, aber es wäre nett mit als allgemeine Lösung für das Problem wie möglich :) – salient

Antwort

3

ich dies mit group by und having nähern. Wenn Sie möchten, 1 und 2 und etwas anderes:

select x 
from t 
where y in (1, 2) 
group by x 
having count(distinct y) = 2; 

Die distinct wäre unnötig, wenn man weiß, dass x/y-Paare waren einzigartig.

Wenn Sie wollten nur 1, denn das ist eine genaue Übereinstimmung ist:

select x 
from t 
group by x 
having sum(case when y = 1 then 1 else 0 end) > 0 and 
     sum(case when y = 2 then 1 else 0 end) > 0 and 
     sum(case when y not in (1, 2) then 1 else 0 end) = 0; 
1

können Sie versuchen, mit count (*) = Anzahl der Element in Array

select x from (
select distinct x, y 
from my_table where y in (1,2)) t 
group by x 
having count(*) = 2 
+0

@salient können Sie doppelte Werte haben, dh (a, 1) und (a, 1)? Wenn nicht, wird das funktionieren. – EoinS

+0

@EoinS - Ja, es kann Fälle geben. – salient

+0

Kann einfach zu count() hinzufügen, um dies zu erledigen – EoinS

1

Diese Lösung aus den anderen Antworten erstellt, aber Sie können Ihre Liste einmal nur einfach hinzufügen, wie erwähnt.

Sie müssen nicht gehen und den Listenwert in Ihrem where Zustand ändern und die Länge Ihrer Liste in der count() Funktion.

declare @list varchar(10) 
set @list = '1,2,3' --you add this list only 

declare @listOfIDs varchar(10); 
SET @listOfIDs = concat(',',@list,','); 

select x 
from p 
where charindex(',' + CAST(p.y as nvarchar(20)) + ',', @listOfIDs) >0 
group by x 
having count(distinct y) = len(@list)-len(replace(@list,',',''))+1; 

können Sie mit den verschiedenen Listen spielen here

Es sollte für Arbeit 1,305,2 etc

+0

Sehr interessante Lösung. Hast du eine Vorstellung davon, wie man das auch mit einer Lösung kombinieren könnte, um all die einzigartigen ** vorkommenden ** Kombinationen in y zu finden? I.e. 1; 2; 3; [1,2]; [1,3]; [2,3]; [1,2,3]? – salient

1

mit der folgenden Abfrage Versuchen.

SELECT X 
FROM #T 
WHERE Y IN (1,2) 
GROUP BY X 
HAVING COUNT(Y)=(SELECT COUNT(DISTINCT Y) FROM #T WHERE Y IN (1,2)) 

Sie können die y-Spaltenwerte in einer Variablen mithilfe der dynamischen Abfrage übergeben.

DECLARE @input VARCHAR(50)='1,2' 

DECLARE @sql NVARCHAR(MAX)= 
    'SELECT X 
    FROM #T 
    WHERE Y IN ('[email protected]+') 
    GROUP BY X 
    HAVING COUNT(Y)=(SELECT COUNT(DISTINCT Y) FROM #T WHERE Y IN ('[email protected]+'))' 
EXEC (@sql) 

Beispielausgabe

enter image description here

Verwandte Themen