und verknüpfte suche über eine kreuztabelle



  • guten abend 🙂

    ich hab ein kleines datenbank-abfrage problem:

    es gibt produkte und kategorien. jedes produkt kann
    n kategorien zugeordnet sein.
    kleines (dummes beispiel):
    das produkt fernseher ist der kategorie glas,plastik und metal zugeordnet.

    das ganze bilde ich folgendermassen in der datenbank ab.
    produkt und kategorie sind 2 tabellen. über eine kreuztabelle
    wird die zuordnung zwischen produkt zu kategorie hergestellt.
    das sieht dann so aus:

    --------------       ----------------       ----------------
    | produkt    |<------| kreuztabelle |------>| kategorie    |
    | -pkProdukt |       | -pkProdukt   |       | -pkKategorie |
    |            |       | -pkKategorie |       |              |
    --------------       ----------------       ----------------
    

    soweit so gut.
    jetzt mein problem.
    ich möchte in EINER sql abfrage alle produkte finden,
    die bestimmten kategorien (glas,plastik) zugeordnet sind.
    die suche ist und verknüft (also alle produkte die sowohl
    der kategorie glas als auch der kategorie plastik zugeordnet
    sind).
    dabei soll jedes gefundene produkt nur EINMAL in der
    ergebnismenge auftauchen.

    ist das überhaupt möglich? hat jemand vielleicht ne gute idee
    wie sich das problem lösen lässt?



  • Ich nehme mal an du hast sowas:

    SELECT * FROM produkte WHERE produkt_id IN (SELECT produkt_id FROM kreuztabelle WHERE kategorie_id IN (SELECT kategorie_id FROM kategorien WHERE kat_name='Glas' OR kat_name='Plastik'));
    

    Dann sollte alles auch nur einmal zurückkommen 😕

    Das innerste SELECT liefert zB 1 und 3. Das nächstinnere SELECT liefert nun alle produkt_id die die kategorie_id 1 oder 3 haben. Da produkt_id alleine kein Primärschlüssel ist kann es mehrmals vorkommen. Also liefert das zB 4 (weil glas), 12 (weil glas), 12(weil plastik), 36 (weil glas). So und nun alle Produkte ausgeben deren produkt_id in der Menge {4,12,12,36} ist. Aber nur weil 12 zweimal in dieser Menge ist heißt das nicht, dass es zweimal ausgegeben wird 😕

    MfG SideWinder



  • das problem das mir zu schaffen macht ist die und-verknüpfung.

    ich kann es erst morgen ausprobieren, glaube aber deine
    abfrage liefer nicht die und verknüpfte menge
    (oder ich habs falsch verstanden :)).

    bsp:

    -----------  ------------------  ----------------
    | produkt |  | kategorie      |  | kreuztabelle |
    | -p1     |  | - k1 (glas)    |  | -p1,k1       |
    | -p2     |  | - k2 (plastik) |  | -p1,k2       |
    |         |  | - k3 (metal)   |  | -p2,k2       |
    |         |  |                |  | -p2,k3       |
    -----------  ------------------  ----------------
    

    wenn ich jetzt alle produkte in der kategorie
    k1 (glas) und k2 (plastik)
    suche müsste als ergebnis
    p1
    geliefert werden (da p2 in den kategorien k2 und
    k3 ist nicht aber in k1).

    deine abfrage gibt mir p1 und p2 zurück; d.h. sie
    ist oder verknüft.



  • Achso, also nicht alle Glas- + alle Plastik-Produkte sondern alle Produkte die unter Glas und Plastik stehen.

    Hmm, schaut nicht sehr toll aus, aber sieht zumindest so aus als würde es funktionieren:

    SELECT distinct k1.produkt_id FROM kreuztabelle k1, kreuztabelle k2 WHERE k1.produkt_id=p2.produkt_id AND k1.kategorie_id=1 AND k2.kategorie_id=3;
    

    MfG SideWinder



  • hm. also erst mal danke fuer deine bemuehungen 😉

    ich konnte das ganze leider nocht nicht ausprobieren.

    zu deinem letzten statement. das muesste ich immer dynamisch
    generieren, oder? also wenn ich nach 3 kategorien
    suche braeuchte ich 3 joins??

    SELECT 
      k1.produkt_id 
    FROM kreuztabelle k1
      inner join kreuztabelle k2 on k1.kategorie_id=k2.kategorie_id
      inner join kreuztabelle k3 on k1.kategorie_id=k3.kategorie_id
    k1.kategorie_id=1 AND 
    k2.kategorie_id=3 AND
    k3.kategorie_id=7
    

    falls ja ists ja auch doof, weil wohl super lahm (gernieren
    der abfrage, durchfuerhen von n joins).

    es sieht fast so aus, als gaebe es keine loesung dafuer.... 😞


Anmelden zum Antworten