Tonicwater: 2 Tabellen vergleichen und Rest auslesen

Hallo,

ich bin noch neu in diesem Bereich und habe nur die Basics drauf. Ich stehe vor folgenden Problem:

Ich habe zwei Tabellen in der DB, welche anhand ihrer Inhalte verglichen werden sollen. Ich würde anschließend gerne den Rest (also das was nicht in beiden Tabellen vorkommt) auslesen und zwar in einer WHILE Schleife (PHP).

Ich habe schon etliche Forenbeiträge durchkämmt. Soweit mir bekannt lässt sich dies nicht mit NOT IN (subselect) lösen sondern eher mit LEFT JOIN?

Theorie:

$query = "SELECT tab_item FROM tab1 WHERE tab_item NOT IN (SELECT tab_item FROM tab2)";
$result = $database->query($query);
while($item = $result->fetchRow($result)){
   echo $item["tab_item"];
}

(obiges fuktioniert nicht)

Danke für eure Hilfe!
TW

  1. Sup!

    Also in PostGreSQL gibt es einen INTERSECT-Operator, der filtert alles raus, was in beiden Tabellen ist.

    Und dann gibt es den EXCEPT-Operator, der findet alles ausser dem, was man ausschliesst.

    Also wäre die Lösung mit PostGreSQL quasi:

    Select * from A EXCEPT (Select * from A INTERSECT B);

    Gruesse,

    Bio

    --
    Never give up, never surrender!!!
    1. Hallo,

      danke für die schnelle Antwort. Leider haut das nicht hin.
      Ich habe übrigens die MySQL Version 4.4.4 (ohne NOT IN Funktion :-( )

      TW

      1. Sup!

        Hmmm... und es geht auch nicht sowas wie:

        select table1.*, table2.* from table1,table2 where (table1.x != table2.x AND table1.y != table2.y (...)).

        UNION

        select table2.*, table1.* (...)

        Gruesse,

        Bio

        --
        Never give up, never surrender!!!
        1. Hallo Bio,

          select table1.*, table2.* from table1,table2 where (table1.x != table2.x AND table1.y != table2.y (...)).

          UNION

          select table2.*, table1.* (...)

          das ist garantiert nicht das gewünschte Ergebnis, auch nicht in PostgreSQL :-)

          Nein, das ist nicht

          SELECT * FROM A EXCEPT B  
          UNION  
          SELECT * FROM B EXCEPT A
          

          Dann schon eher

          SELECT  
              COALESCE(A.tab_item, B.tab_item) AS item  
          FROM A  
          FULL OUTER JOIN B  
          ON A.tab_item = B.tab_item  
          WHERE A.tab_item IS NULL OR B.tab_item IS NULL
          

          wenn das DBMS den FULL OUTER JOIN unterstützt.

          Freundliche Grüße

          Vinzenz

          1. Hallo,

            Ihr seid genial - vielen Dank für euren Support!

            Ich habe schlicht nicht alles ausporbiert!

            TW

      2. Hallo

        Ich habe übrigens die MySQL Version 4.4.4 (ohne NOT IN Funktion :-( )

        Diese MySQL-Version gibt es nicht. NOT IN ist schon urlange dabei. Hast Du eventuell eine 4.0.x, dann müsstest Du meinen Vorschlag mit LEFT JOIN umsetzen. Die Technik habe ich erst unlängst erläutert.

        UNION wird von 4.0.x bereits unterstützt, Subselects gehen erst ab 4.1.x.

        Freundliche Grüße

        Vinzenz

  2. Hallo

    Ich habe zwei Tabellen in der DB, welche anhand ihrer Inhalte verglichen werden sollen. Ich würde anschließend gerne den Rest (also das was nicht in beiden Tabellen vorkommt) auslesen und zwar in einer WHILE Schleife (PHP).

    Verstehe ich Dich richtig:

    Du möchtest die Zeilen ausgeben, die genau in einer der beiden Tabellen vorkommen.

    Ich habe schon etliche Forenbeiträge durchkämmt. Soweit mir bekannt lässt sich dies nicht mit NOT IN (subselect) lösen sondern eher mit LEFT JOIN?

    Dann ist Dir nicht alles bekannt :-) Sowohl LEFT JOIN als auch NOT IN läßt sich für Dein Problem verwenden.

    (obiges fuktioniert nicht)

    "Funktioniert nicht" ist leider keine Fehlerbeschreibung:
    Welches Ergebnis erhältst Du?
    Welches Ergebnis erwartest Du?
    Wo liegt die Abweichung vom erwarteten Ergebnis?

    Zurück zu Deinem Problem:

    Du suchst die Datensätze, die in der Vereinigungsmenge der beiden Tabellen vorkommen, aber nicht in der Schnittmenge:

    Gib mir alle Datensätze, die in Tabelle tab1 vorkommen, aber nicht in Tabelle tab2. Nimm dazu alle Datensätze, die in Tabelle tab2 vorkommen, aber nicht in Tabelle tab1:

    SELECT                        -- Gib mir alle  
        tab1.tab_item             -- Items  
    FROM tab1                     -- aus Tabelle tab1,  
    WHERE tab1.tab_item NOT IN (  -- die nicht  
        SELECT                    -- in den  
            tab2.tab_item         -- Items  
        FROM tab2                 -- aus Tabelle tab2  
    )                             -- vorkommen  
    UNION         -- und nehme dazu  
    SELECT                        -- alle  
        tab2.tab_item             -- Items  
    FROM tab2                     -- aus Tabelle tab2,  
    WHERE tab2.tab_item NOT IN (  -- die nicht  
        SELECT                    -- in den  
            tab1.tab_item         -- Items  
        FROM tab1                 -- aus Tabelle tab1  
    )                             -- vorkommen  
    
    

    Analog könntest Du das mit 2x LEFT JOIN und UNION aufbauen, geht auch.
    Eine weitere Möglichkeit hättest Du mit einem FULL JOIN und diversen Funktionen wie COALESCE() ...

    Viele Wege führen zum gewünschten Ergebnis, hoffentlich unterstützt Dein Datenbankmanagementsystem die entsprechende Abfrage.

    Freundliche Grüße

    Vinzenz

    1. Sup!

      Ja, wenn alles PostGreSQL hätten ;-)

      Gruesse,

      Bio

      --
      Never give up, never surrender!!!