Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

SQL-Abfrage

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von derdieter, 6 April 2017.

  1. derdieter

    derdieter Neuer Benutzer

    Hallo zusammen,

    ich habe folgendes Problem, bei dem ich nicht weiterkomme.

    Ich habe eine Tabelle "Lieferanten":

    ID | Lieferant
    1 | Lieferant A
    2 | Lieferant B
    3 | Lieferant C

    Und ich habe eine Tabelle "Artikel":

    ID | Artikel
    1 | Äpfel
    2 | Birnen
    3 | Bananen
    4 | Zitronen

    Dann habe ich eine Tabelle LieferantArtikel, also welche Lieferanten welche Artikel liefern können.

    ID | LieferantID | ArtikelID
    1 | 1 | 1
    2 | 1 | 2
    3 | 1 | 3
    4 | 1 | 4
    5 | 2 | 1
    6 | 2 | 3
    7 | 2 | 4
    7 | 3 | 3
    7 | 4 | 4

    Nun möchte ich per Abfrage alle Lieferanten erhalten, die z.B. Äpfel UND Bananen liefern können (Ergebnis also Lieferant A und Lieferant B).

    Wie muss dazu die SQL-Abfrage lauten?

    Danke für Eure Hilfe.

    Grüße
    Dieter
     
  2. BerndB

    BerndB Datenbank-Guru

    Hier eine Lösung:

    Code:
    SELECT l.lieferant, max.anz
    FROM Lieferanten l
    LEFT JOIN LieferantArtikel la ON la.lieferantID = l.id
    LEFT JOIN Artikel a ON a.id = la.ArtikelID
    CROSS JOIN ( SELECT @art:='Äpfel,Bananen') AS init
    CROSS JOIN ( SELECT count(*) AS anz FROM Artikel a WHERE FIND_IN_SET(a.Artikel,@art) ) AS max
    WHERE
        FIND_IN_SET(a.Artikel,@art)
    GROUP BY
        l.Lieferant
    HAVING
        count(l.lieferant) = max.anz;
    Beispiel:

    Code:
    mysql> SELECT l.lieferant, max.anz
        -> FROM Lieferanten l
        -> LEFT JOIN LieferantArtikel la ON la.lieferantID = l.id
        -> LEFT JOIN Artikel a ON a.id = la.ArtikelID
        -> CROSS JOIN ( SELECT @art:='Äpfel,Bananen') AS init
        -> CROSS JOIN ( SELECT count(*) AS anz FROM Artikel a WHERE FIND_IN_SET(a.Artikel,@art) ) AS max
        -> WHERE
        ->     FIND_IN_SET(a.Artikel,@art)
        -> GROUP BY
        ->     l.Lieferant
        -> HAVING
        ->     count(l.lieferant) = max.anz;
    +-------------+-----+
    | lieferant   | anz |
    +-------------+-----+
    | Lieferant A |   2 |
    | Lieferant B |   2 |
    +-------------+-----+
    2 rows in set (0,00 sec)
    
    mysql>
     
  3. derdieter

    derdieter Neuer Benutzer

    Hi,

    danke erstmal für deine Lösung. Ich hätte allerdings dazu schreiben sollen, dass es sich um ein vb.net Projekt und eine Access-DB handelt. Da funktioniert die Lösung scheinbar nicht. Wie müsste das dann aussehen?

    Grüße
    Dieter
     
  4. ukulele

    ukulele Datenbank-Guru

    Also es gibt mehrere Lösungen, vergleichsweise viele sogar. Einige davon besonders elegant und vermutlich auch performant, einige davon recht simpel gestrickt und vermutlich einfacher zu verstehen. Hier ein Beispiel das in jedem SQL laufen sollte (sogar in Access :) ):
    Code:
    SELECT   *
    FROM   Lieferant
    WHERE   ID IN (   SELECT   LieferantArtikel.LieferantID
             FROM   LieferantArtikel
             INNER JOIN Artikel
             ON     LieferantArtikel.ArtikelID = Artikel.ArtikelID
             AND     Artikel.Artikel = 'Äpfel' )
    AND     ID IN (   SELECT   LieferantArtikel.LieferantID
             FROM   LieferantArtikel
             INNER JOIN Artikel
             ON     LieferantArtikel.ArtikelID = Artikel.ArtikelID
             AND     Artikel.Artikel = 'Bananen' )
     
    BerndB gefällt das.
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden