Gernold Raubach: unkorrekte SQL Abfrage: Newbie sucht Hilfe

Hallo,

ich habe eine Abfrage über zwei Tabellen zu machen, die folgenden Sinn haben soll:

Zeige mir alle Kunden (Tabelle user), die nichts gekauft haben (Tabelle order) und keinen Newsletter wünschen

Alle Kundendaten liegen in "user"
Alle Käufe werden in "order" gelistet

Die Kunden ID ist "id" in der user Tabelle, "customer" in der order Tabelle

Meine SQL:

select t1.last_name, t1.first_name, t1.email from user AS t1, order as t2 WHERE t1.id != t2.customer AND t1.newsletter = 0

Es gibt zwar ein Ergebnis, aber das kann nicht korrekt sein (>60000 Einträge bei 1000 Kunden)

Ich vermute das "!=" kann so nicht benutzt werden?
Danke Euch,

Gernold

  1. Zeige mir alle Kunden (Tabelle user), die nichts gekauft haben...
    => Dann sollten wir das auch noch (richtig) abfragen...!?!?!

    Ich vermute das "!=" kann so nicht benutzt werden?

    => Bin mir zwar auch nicht sicher aber veruch es doch mal mit <>

    1. Hallo!

      Alle Eure Antworten waren sehr hilfreich (Problem gelöst) und lehrreich (wieder was verstanden).

      Danke für Eure kompetente Hilfe.

      Euch allen einen schönen Tag,
      Gernold

  2. Hello,

    wie in so vielen Fällen hängt vieles von der genauen Version der dir zur Verfügung stehenden Software ab. Die aus meiner Sicht intuitivste Variante einer Abfrage sieht wie folgt aus:

      
    SELECT last_name, first_name, email  
    FROM user                              -- gib mir alle Nutzer  
    WHERE id NOT IN (                      -- die NICHT unter den Käufern sind  
       SELECT customer FROM order  
    )  
    AND newsletter = 0                     -- und keinen Newsletter wünschen  
    
    

    Nun ist es allerdings so, dass insbesondere ältere MySQL-Datenbanken diese Syntax verweigern, in diesem Fall muss man in der Tat auf Joins ausweichen. Um zu verstehen, was du geschrieben hast und welche Wirkung das hat, solltest du dir erstmal die Joins genauer ansehen - SELFHTML hat eine eigene Sektion mit Artikeln zum Thema Datenbanken.
    Wir brauchen also einen JOIN der uns gestattet passende Datensätze rauszufiltern, also in etwa so:

      
    SELECT user.last_name, user.first_name, user.email, order.customer AS filterkriterium  
    FROM user LEFT JOIN order  
    ON user.id = order.customer  
    WHERE filterkriterium IS NULL    -- es wurde keine Übereinstimmung gefunden  
    AND user.newsletter = 0          -- er wünscht keinen Newsletter  
    
    

    MfG
    Rouven

    --
    -------------------
    Let Bygones Be Bygones  --  Robert Pitscottie: "Chronicles of Scotland"
  3. Hallo

    Zeige mir alle Kunden (Tabelle user), die nichts gekauft haben (Tabelle order) und keinen Newsletter wünschen

    d.h. die Kunden, zu denen keine Einträge in order vorhanden sind.
    und einen speziellen Eintrag in der Spalte newsletter der Tabelle user haben.

    Alle Kundendaten liegen in "user"
    Alle Käufe werden in "order" gelistet

    Die Kunden ID ist "id" in der user Tabelle, "customer" in der order Tabelle

    Meine SQL:

    select t1.last_name, t1.first_name, t1.email from user AS t1, order as t2 WHERE t1.id != t2.customer AND t1.newsletter = 0

    Nein, auch der von Peter erwähnte Ungleichoperator ist nicht sinnvoll. Das wäre nämlich ein sogenannter Thetajoin., der eben ganz anderes liefert als die von Dir gewünschten Daten. Dein Problem lässt sich z.B. mit einem LEFT JOIN oder einem Subselect (MySQL 4.1 oder neuer) lösen:

    SELECT  
        u.last_name,  
        u.first_name,  
        u.email,  
    FROM user u  
    LEFT JOIN `order` o   -- order ist meiner Meinung nach ein schlechter  
                          -- Spaltenname, da ein [link:http://dev.mysql.com/doc/refman/4.1/en/reserved-words.html@title=reserviertes Wort].  
                          -- Ich persönlich vermeide lieber solche Namen.  
    ON u.id = o.customer  
    WHERE  
        u.newsletter = 0  -- kein Newsletter  
        AND o.customer [link:http://dev.mysql.com/doc/refman/4.1/en/comparison-operators.html#id3004919@title=IS NULL] -- kein Eintrag in der Tabelle order zu dieser Person  
    
    

    geht mit jeder mir bekannten MySQL-Version, sogar 3.23. Die Subselect-Variante ist möglicherweise performanter (nutze dazu EXPLAIN):

    SELECT  
        u.last_name,  
        u.first_name,  
        u.email,  
    FROM user u  
    LEFT JOIN `order` o  
    ON u.id = o.customer  
    WHERE  
        u.newsletter = 0  -- kein Newsletter  
        AND u.id NOT IN (SELECT o2.customer FROM `order` o2)  
            -- kein Eintrag in der Tabelle order zu dieser Person  
    
    

    geht aber, wie bereits bemerkt, erst ab MySQL 4.1 [1].

    Freundliche Grüße

    Vinzenz

    [1] <gebetsmühle>
            Bei Fragen zu MySQL ist es eine gute Idee, die verwendete Version
            anzugeben, da sich die Fähigkeiten von MySQL zwischen den Versionen
            zum Teil sehr stark unterscheiden.
        </gebetsmühle>

    1. Hallo Ingrid,

      trotz Vorschau Syntaxfehler :-(

      Zeige mir alle Kunden (Tabelle user), die keinen Newsletter wünschen und nichts gekauft haben (Tabelle order)

      SELECT  
          u.last_name,  
          u.first_name,  
          u.email           -- da gehört kein Komma hin :-)  
      FROM user u  
      LEFT JOIN `order` o   -- order ist meiner Meinung nach ein schlechter  
                            -- Spaltenname, da ein [link:http://dev.mysql.com/doc/refman/4.1/en/reserved-words.html@title=reserviertes Wort].  
                            -- Ich persönlich vermeide lieber solche Namen.  
      ON u.id = o.customer  
      WHERE  
          u.newsletter = 0  -- kein Newsletter  
          AND o.customer [link:http://dev.mysql.com/doc/refman/4.1/en/comparison-operators.html#id3004919@title=IS NULL] -- kein Eintrag in der Tabelle order zu dieser Person  
      
      

      geht mit jeder mir bekannten MySQL-Version, sogar 3.23. Die Subselect-Variante ist möglicherweise performanter (nutze dazu EXPLAIN):

      SELECT  
          u.last_name,  
          u.first_name,  
          u.email            -- da auch nicht  
      FROM user u  
      LEFT JOIN `order` o  
      ON u.id = o.customer  
      WHERE  
          u.newsletter = 0  -- kein Newsletter  
          AND u.id NOT IN (SELECT o2.customer FROM `order` o2)  
              -- kein Eintrag in der Tabelle order zu dieser Person  
      
      

      geht aber, wie bereits bemerkt, erst ab MySQL 4.1 [1].

      Freundliche Grüße

      Vinzenz