none
SQL-Abfrage: alle Werte, welche mindestens einen Wert 1 und 2 haben RRS feed

  • Frage

  • Hallo,

    ich habe eine Tabelle mit folgenden Einträgen

    ID1    ID2

    1       aa
    4       aa
    1       bb
    4       cc

    Ich möchte jetzt eine SQL-Abfrage, welche mir nur die ID2-Werte liefert, welche in ID1 sowohl 1 alsauch 4 haben, in obigem Beispiel also aa, nicht bb und nicht cc.

    Ich stehe da im Moment etwas auf dem Schlauch...

    Grüße

    Stefan

    Mittwoch, 5. März 2014 12:20

Antworten

  • Vielleicht nicht die performanteste Lösung, aber ein Ansatz:

    select ID2 from
    (select distinct ID1, ID2 
    from tab where ID1 in (select ARTIKEL_ID from Liste)) t1
    group by ID2
    having count(*) = (select count(distinct ARTIKEL_ID) from Liste)

    Die Subselects eventuell ergänzt um eine entsprechende Where-Klausel um die richtige Artikelliste zu erwischen oder ersetzt durch eine Aufzählung im Where und der Artikel-Gesamtzahl im Having.

    Mittwoch, 5. März 2014 22:46
  • Hallo Stefan,
    normalerweise könnte man so etwas mit entsprechenden AND-Bedingungen abbilden. Bei wechselnden Artikeln und wechselnder Anzahl kommt da aber keine Freude auf. Ich hatte kürzlich für einen Kollegen aus der PASS-Gruppe eine ähnliche Fragestellung über ein Konstrukt mit einer Filtertabelle gelöst. Ich habe es mal für Dich angepasst. HTH!

    Declare @tab as table (Kunde int, Artikel varchar(5));
    
    Insert into @tab(Kunde, Artikel) values (1, '101');
    Insert into @tab(Kunde, Artikel) values (1, '102');
    Insert into @tab(Kunde, Artikel) values (2, '101');
    Insert into @tab(Kunde, Artikel) values (2, '102');
    Insert into @tab(Kunde, Artikel) values (2, '103');
    Insert into @tab(Kunde, Artikel) values (3, '101');
    Insert into @tab(Kunde, Artikel) values (3, '103');
    
    Declare @Suchmaske as table (Artikel varchar(5));
    Insert into @Suchmaske(Artikel) Values('101');
    Insert into @Suchmaske(Artikel) Values('103');
     -- Prüfung mit CTE und Join
    With Vorberechnung as
    (Select t1.Kunde, count(*) as Anzahl
    from @tab t1
    Inner Join @Suchmaske s1 on t1.Artikel = s1.Artikel
    group by Kunde
    )
    Select Distinct Kunde
    from Vorberechnung v
    where v.Anzahl = (Select count(*) from @Suchmaske)
    ;

    Das Beispiel findet also alle Kunden, die Artikel 101 und Artikel 103 gekauft haben.

    Ansonsten kann ich die Aussage von Stefan Falz zur unterstützen, damit wir wirklich zielorientiert an Deiner Fragestellung arbeiten können.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Donnerstag, 6. März 2014 07:10

Alle Antworten

  • Hallo Stefan,
    probiere die SQL am Ende bitte aus. Davon ausgehend das die Tabelle tab heißt.

    --create table tab (id1 int , id2 varchar(30) )
    
    --insert into tab (id1, id2 ) values(1,'aa')
    --insert into tab (id1, id2 ) values(4,'aa')
    --insert into tab (id1, id2 ) values(1,'bb')
    --insert into tab (id1, id2 ) values(4,'cc')
    
    
    select t1.id1 , t1.id2 , t2.id1, t2.id2
    from 
    tab as t1 
    inner join tab  as t2 on t1.ID2 = t2.ID2
    where
    t1.ID1 =1 and t2.id1 =4
    

    Grüße Alexander

    Mittwoch, 5. März 2014 12:33
  • Danke. Meine 4 Zeilen waren aber nur ein Beispiel.

    Nehmen wir an die Tabelle enthält mehrere Millionen Datensätze - alles Kombinationen aus belibigen ID1 mit beliebigen ID2. Die Fragestellung ist die gleiche:

    Wie erhalte ich alle Datensätze, welche ein identisches ID2 haben aber z. B.100 ID1 also ID1 in (1,2,3,5,7,8,9,10,34,4,67,33,53,43...)?

    Ich kann da ja im SQL schlecht für jedes ID1/ID2 einen Alias anlegen. Was ist die Alternative?

    Grüße

    Stefan


    • Bearbeitet Stefan_ Mittwoch, 5. März 2014 13:22
    Mittwoch, 5. März 2014 13:10
  • Hallo Stefan,

    nuja, deine Beschreibung sprach explizit von 2 bestimmten Werten, die Du für den Vergleich heranziehen willst.

    Wenn Du nur wissen willst, welche ID2 mehrfach vorkommt:

    SELECT ID2
    FROM   Tabelle
    GROUP  BY ID2
    HAVING COUNT( 1 ) > 1
    

    Wenn Du eine Kombination aus ID1 und ID2 auch mehrfach vorkommen könnte, dann in etwa sowas:

    WITH Query AS
    (
    SELECT DISTINCT ID1, ID2 FROM Tabelle
    )
    SELECT ID2
    FROM   Query
    GROUP  BY ID2
    HAVING COUNT( 1 ) > 1
    


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 5. März 2014 13:52
    Moderator
  • Hallo Stefan,
    davon ausgehend das Du eindeutige Kombinationen hast die erlaubt sind 
    Schau mal ob das hier trifft. Die Paare wären dann in der Tabelle Paare
    zu ergänzen und bei deinen Mengenangaben soll noch ein Index helfen. create table tab (id1 int , id2 varchar(30) ) insert into tab (id1, id2 ) values(1,'aa') insert into tab (id1, id2 ) values(4,'aa') insert into tab (id1, id2 ) values(1,'bb') insert into tab (id1, id2 ) values(4,'cc') create table paare (wert1 int , wert2 int) insert into paare (wert1 , wert2) values(1,4) insert into paare (wert1 , wert2) values(2,9) select t1.id1 , t1.id2 , t2.id1, t2.id2 from tab as t1 inner join tab as t2 on t1.ID2 = t2.ID2 inner join paare on t1.id1=paare.wert1 and t2.id=paare.wert2 Grüße Alexander

    Mittwoch, 5. März 2014 13:56
  • Vielen Dank für die Infos aber das hilft mir alles nicht weiter. Ich fange nochmals ganz von vorne an und mache das ganze etwas konkreter:

    Ich habe Artikel, jeder Artikel hat eine Nummer.

    Ich habe Kunden. Jeder Kunde hat eine Nummer.

    Es gibt eine Tabelle (die, um die es hier geht) welche eine Relation speichert, welchen Artikel ein Kunde gekauft hat.

    Wenn also Artikel 1 von Kunde A gekauft wurde dann steht in der Tabelle ID1=1 und ID2=A.

    Jetzt kommt die Frage: Zeige mir alle Kunden, welche alle Artikel einer Liste gekauft haben, also gib mir die Kunden, welche Artikel 1,5,9,10,15 gekauft haben aber halt nur die Kunden, welche wirklich alle Artikel der genannten Liste gekauft haben und nicht nur einen Artikel davon. Die Liste mit den Artikeln kann beliebig lang sein.

    Wie lautet hier der SQL?

    Grüße

    Stefan


    • Bearbeitet Stefan_ Mittwoch, 5. März 2014 15:09
    Mittwoch, 5. März 2014 15:08
  • Hallo Stefan,

    es wäre hilfreich, wenn Du die Tabellenstruktur (bitte als CREATE TABLE Statements) sowie einige Beispieldatensätze (bitte als INSERT INTO Statements) und dazu das gewünschte Ergebnis hier posten könntest. (wenn machbar, aber bitte mit ein paar mehr Daten und verschiedenen Abfragen, die deinen Anforderungen entsprechen)

    Ich denke zwar, dass jetzt klarer ist, was Du willst aber dennoch würde ich es als sinnvoll ansehen, wenn Du die Vorarbeit wie obenstehend beschrieben machen würdest und wir dann darauf aufsetzend weitermachen können.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Mittwoch, 5. März 2014 15:56
    Moderator
  • Vielleicht nicht die performanteste Lösung, aber ein Ansatz:

    select ID2 from
    (select distinct ID1, ID2 
    from tab where ID1 in (select ARTIKEL_ID from Liste)) t1
    group by ID2
    having count(*) = (select count(distinct ARTIKEL_ID) from Liste)

    Die Subselects eventuell ergänzt um eine entsprechende Where-Klausel um die richtige Artikelliste zu erwischen oder ersetzt durch eine Aufzählung im Where und der Artikel-Gesamtzahl im Having.

    Mittwoch, 5. März 2014 22:46
  • Hallo Stefan,
    normalerweise könnte man so etwas mit entsprechenden AND-Bedingungen abbilden. Bei wechselnden Artikeln und wechselnder Anzahl kommt da aber keine Freude auf. Ich hatte kürzlich für einen Kollegen aus der PASS-Gruppe eine ähnliche Fragestellung über ein Konstrukt mit einer Filtertabelle gelöst. Ich habe es mal für Dich angepasst. HTH!

    Declare @tab as table (Kunde int, Artikel varchar(5));
    
    Insert into @tab(Kunde, Artikel) values (1, '101');
    Insert into @tab(Kunde, Artikel) values (1, '102');
    Insert into @tab(Kunde, Artikel) values (2, '101');
    Insert into @tab(Kunde, Artikel) values (2, '102');
    Insert into @tab(Kunde, Artikel) values (2, '103');
    Insert into @tab(Kunde, Artikel) values (3, '101');
    Insert into @tab(Kunde, Artikel) values (3, '103');
    
    Declare @Suchmaske as table (Artikel varchar(5));
    Insert into @Suchmaske(Artikel) Values('101');
    Insert into @Suchmaske(Artikel) Values('103');
     -- Prüfung mit CTE und Join
    With Vorberechnung as
    (Select t1.Kunde, count(*) as Anzahl
    from @tab t1
    Inner Join @Suchmaske s1 on t1.Artikel = s1.Artikel
    group by Kunde
    )
    Select Distinct Kunde
    from Vorberechnung v
    where v.Anzahl = (Select count(*) from @Suchmaske)
    ;

    Das Beispiel findet also alle Kunden, die Artikel 101 und Artikel 103 gekauft haben.

    Ansonsten kann ich die Aussage von Stefan Falz zur unterstützen, damit wir wirklich zielorientiert an Deiner Fragestellung arbeiten können.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Donnerstag, 6. März 2014 07:10
  • Hallo Stefan,

    Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
    Wenn nicht, neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.

    Danke und viele Grüße,
    Ionut


    Ionut Duma, MICROSOFT   Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-PrinzipEntwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Donnerstag, 20. März 2014 13:41
    Moderator