Ankündigung

Einklappen
Keine Ankündigung bisher.

Restmenge --> Reverse Join?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Restmenge --> Reverse Join?

    Hi zusammen

    Ich bin mal wieder auf ein (für mich) interessantes Problem gestossen. Ich habe folgende Tabellen:

    tab1.
    Pid | Kid | Name | Preis
    -----------------------------
    1 | 1 | A | 99
    2 | 1 | B | 99
    3 | 2 | C | 99
    4 | 1 | D | 99

    tab 2.
    Vid | Pid | Kd | Menge
    --------------------
    1 | 1 | 1 | 3
    2 | 2 | 1 | 5
    3 | 3 | 2 |10
    4 | 1 | 2 | 7

    Als Resultat möchte ich folgende Daten haben:

    Pid | Name
    -------------
    4 | D

    Ich möchte gerne alle Datensätze aus Tabelle 1, welche als Fremdschlüssel Kid 1 haben und nicht in Tabelle 2 auftauchen wo Kd als Wert 1 besitzt. Ich schaffe es, alle aus zu geben, welche in Tabelle 2 auftauchen, allerdings bräuchte ich genau die Restmenge von der Abfrage! Ich komme trotz aller NOT's und ! nicht zu dem gewünschten Resultat! Wer hat mir nen Denkanstoss?

    Von diesem Query bräuchte ich eben genau die Restmenge:
    Code:
    SELECT t1.Pid, t1.Name
    FROM tabelle1 t1
    JOIN tabelle2 t2 ON t2.Pid = t1.Pid
    WHERE t1.Kid = 1 AND t2.Kd = 1

  • #2
    Du musst dein Problem einfach nur in seine Einzelanforderungen zerlegen:
    alle Datensätze aus Tabelle 1, welche als Fremdschlüssel Kid 1
    Code:
    SELECT * FROM tab1 WHERE kid = 1
    oder JOIN-vorbereitet:
    Code:
    SELECT DISTINCT tab1.* FROM tab1 WHERE tab1.kid = 1
    * zu DISTINCT; verknüpfen wir beide Tabellen jetzt ersteinmal:
    Code:
    INNER JOIN tab2 ON tab1.pid = tab2.pid
    Weiter mit der nächsten Bedingung:
    und nicht in Tabelle 2 auftauchen wo Kd als Wert 1 besitzt
    (schlecht formuliert, aber egal)
    Code:
    tab2.kd != 1
    Damit hätten wir:
    Code:
    SELECT DISTINCT tab1.* FROM tab1 INNER JOIN tab2 ON tab1.pid = tab2.pid AND tab2.kd != 1 WHERE tab1.kid = 1
    Das sollte es sein!



    * = DISTINCT übrigens deswegen, weil ein JOIN bei einer n:m Beziehung sonst mehrfach auftauchen könnte, wenn die Bedingung eben auch mehrfach zutrifft. Ich weiß nicht ob das bei deinem Fall sein kann/soll.

    Kommentar


    • #3
      Zitat von Zergling
      und nicht in Tabelle 2 auftauchen wo Kd als Wert 1 besitzt
      (schlecht formuliert, aber egal)
      Code:
      tab2.kd != 1
      Damit hätten wir:
      Code:
      SELECT DISTINCT tab1.* FROM tab1 INNER JOIN tab2 ON tab1.pid = tab2.pid AND tab2.kd != 1 WHERE tab1.kid = 1
      Das sollte es sein!
      Hi Zergling!
      Danke für deinen Ansatz. Leider habe ich mich in der Tat schlecht ausgedrückt, aber nach 3h vor dieser Problematik hat sich in meinem Kopf alles gedreht!
      Habe auf jeden Fall schon gelernt, dass man über mehr als nur 1 Schlüssel joinen kann... Leider liefert mir die Abfrage nicht ganz das gewünschte Resultat!

      Ich versuche es mal anders zu erklären:

      Code:
      SELECT * FROM tab1 WHERE kid = 1
      ergibt folgende Tabelle:

      Pid | Kid | Name | Preis
      ----------------------------
      1 | 1 | A | 99
      2 | 1 | B | 99
      4 | 1 | D | 99

      Aus dieser Tabelle möchte ich nur jene Datensätze, bei welchen Pid von keinem Datensatz in Tabelle 2 referenziert wird, bei dem Kd = 1 ist.

      Illustriert:
      Code:
      SELECT * FROM tab2 WHERE kd = 1
      ergibt folgende Tabelle:

      Vid | Pid | Kd | Menge
      ----------------------------
      1 | 1 | 1 | 3
      2 | 2 | 1 | 5

      Nun möchte ich gerne den Auschluss aus diesen 2 Tabellen erreichen. Pid 1 und 2 werden jeweils in einem Datensatz referenziert, in dem Kd = 1 ist. Es bleibt also aus Tabelle 1 nur noch der Datensatz mit Pid 4 welcher in keinem Datensatz mit Kd = 1 in Tabelle 2 steht.

      So, ich hoffe auch die letzten Bisschen Klarheit aus der Welt geschafft zu haben! :wink: [/code]

      Kommentar


      • #4
        Bin gerade etwas verwirrt, und weiß nicht ob das jetzt zufällig geklappt hat:
        Code:
        SELECT * FROM tab1 WHERE kid = 1 AND pid NOT IN (SELECT pid FROM tab2 WHERE kd = 1)
        Erklär sonst das Problem doch mal wie es sich tatsächlich gibt, vid pid kid, da kann ich mir nichts drunter vorstellen, da fang ich dann schnell an zu raten

        Kommentar


        • #5
          Hey!

          War gerade eben aufm Klo und da ist mir die genau gleiche Idee gekommen! Dürfte tatsächlich hinhauen!
          Finde es zwar bissi unschön, so n'verschachteltes Query! Wollte das über JOIN packen, wird aber wohl nicht möglich sein und daher ist mir die Lösung recht! Danke vielmals!

          Kommentar


          • #6
            Finde es zwar bissi unschön, so n'verschachteltes Query!
            Quatsch das ist ziemlich mächtig, performant und selbsterklärend fast auch schon! Kein Grund das unschön zu nennen
            Musst halt nur schauen, dass du auch MySQL 4.1 hast, vorher werden Subselects nicht unterstützt.

            Kommentar

            Lädt...
            X