sceiler: "Fehlerhafte" Einträge anzeigen lassen

Hallo,

ich habe folgende Abfrage:

SELECT h.*  
FROM haupt h, company c  
WHERE h.companyId = c.id  

Diese gibt anstandslos 3000 Einträge zurück. So weit so gut.

Wenn ich jedoch

SELECT COUNT(h.companyId)  
FROM haupt h

mache bekomme ich 5000 Einträge zurück.

Gibt es eine Abfrage mit der ich herausfinden kann was mit den anderen 2000 Einträgen ist? Anzeigen? etc.?

  1. Tach!

    Gibt es eine Abfrage mit der ich herausfinden kann was mit den anderen 2000 Einträgen ist? Anzeigen? etc.?

    Die werden sich nicht mit der company-Tabelle verbunden lassen haben.

    Wenn du die obige Abfrage ein wenig modifizierst, so dass du nur die h.id in der Ergebnismenge hast, dann kannst du sie als Subquery verwenden, für eine Abfrage auf die Tabelle haupt, eingeschränkt auf alle Datensätzen, bei denen die id NOT IN(subquery) ist.

    dedlfix.

    1. Ha,
      da hab ich garnicht dran gedacht.
      Das wäre auch noch ne Möglichkeit! :)

    2. Wenn du die obige Abfrage ein wenig modifizierst, so dass du nur die h.id in der Ergebnismenge hast, dann kannst du sie als Subquery verwenden, für eine Abfrage auf die Tabelle haupt, eingeschränkt auf alle Datensätzen, bei denen die id NOT IN(subquery) ist.

      Kannst du das bitte noch einmal erklären? Ich verstehe nicht ganz was du meinst.

      Ich mache ein Query auf die Tabelle haupt mit einem SUBSELECT die alle companyId enthält und schaue wo diese nicht enthalten ist?

      so?

        
      SELECT *  
      FROM haupt h, company c  
      WHERE h.companyId NOT IN (SELECT h.companyId FROM haupt h, company c WHERE h.companyId = c.id)
      
      1. Tach!

        Wenn du die obige Abfrage ein wenig modifizierst, so dass du nur die h.id in der Ergebnismenge hast, dann kannst du sie als Subquery verwenden, für eine Abfrage auf die Tabelle haupt, eingeschränkt auf alle Datensätzen, bei denen die id NOT IN(subquery) ist.
        Kannst du das bitte noch einmal erklären? Ich verstehe nicht ganz was du meinst.

        Du brauchst von den 3000 Datensätzen jeweils einen eindeutigen Identifizierer, damit du genau diese Datensätze ausschließen kannst.

        Ich mache ein Query auf die Tabelle haupt mit einem SUBSELECT die alle companyId enthält und schaue wo diese nicht enthalten ist?

        SELECT *

        FROM haupt h, company c
        WHERE h.companyId NOT IN (SELECT h.companyId FROM haupt h, company c WHERE h.companyId = c.id)

        
        > so?  
          
        Nein, ich sagte Query auf Tabelle haupt, nicht haupt und company. Dann sagte ich id und nicht companyId. (Wobei das h.companyId in der Verknüpfungsbedingung der Subquery stehenbleiben muss, aber eben nur dieses eine.)  
          
          
        dedlfix.
        
        1. So?

          SELECT h.*  
          FROM haupt h  
          WHERE h.companyId NOT IN (SELECT h.companyId FROM haupt h, company c WHERE h.companyId = c.id)
          

          Anm.: die h.companyId ist dieselbe wie in c.id... die spalten heißen nur anders...

          1. Tach!

            So?

            Nein, schreibe ich undeutlich?

            SELECT h.*

            FROM haupt h
            WHERE h.companyId NOT IN (SELECT h.companyId FROM haupt h, company c WHERE h.companyId = c.id)

            
            >   
            > Anm.: die h.companyId ist dieselbe wie in c.id... die spalten heißen nur anders...  
              
            h.companyId ist ein Verweis auf die company-Tabelle. In Tabelle haupt kann es mehrere Datensätze mit demselben Wert für h.companyId geben. Damit kannst du keine Datensätze in haupt identifizieren, denn dazu brauchst du einen einmaligen Wert. Der steht (vermutlich) in der Spalte id der Tabelle haupt. Deswegen sollst du in der Subquery diese IDs ermitteln und in der Haupt-Query ebenfalls gegen diese IDs vergleichen.  
              
            Du kannst dein Ziel aber auch anders erreichen. Meine Lösung funktioniert generell (wenn richtig umgesetzt), auch wenn noch mehr einschränkende Bedingungen hinzukämen. Sie identifiziert in der Subquery die guten Datensätze, die in der Haupt-Query ausgeschlossen werden sollen. In deinem Fall willst du im Grunde genommen alle Datensätze aus haupt, deren companyId nicht in der Tabelle company enthalten ist. Damit kannst du die Hauptquery so lassen, wie sie oben steht und musst in der Subquery nur alle id aus company ermitteln (also ganz einfache Query ohne Join).  
              
              
            dedlfix.
            
            1. Hi,

              endlich hat es geklappt und ich hab es verstanden.

              Vielen Dank!

              Weißt du vllt. noch ob es eine Möglichkeit gibt beide Abfragen zu verbinden?

              SELECT h.name, COUNT(h.id)  
              FROM haupt h, company c  
              WHERE h.companyId = c.id  
              GROUP BY h.name  
              ORDER BY h.id  
                
              SELECT COUNT(h.id)  
              FROM haupt h  
              WHERE h.companyId NOT IN (SELECT c.id FROM company c)
              

              Die 1. Abfrage liefert mir ja nämlich die einzelnen Namen und die dazugehörige Anzahl an Datensätzen.
              Ich brauche aber noch die fehlenden aus dem 2. Query. Die dürfen nicht in der Statistik fehlen.

              Ich hab mir gedacht den Inhalt aus dem 2. Query in den 1. Query zu schreiben den die Werte aus der DB werden ja in einem Array gespeichert.

              So:

              $query1[] = $query2

              aber bekomme dann die Fehldermeldung:  Cannot use a scalar value as an array in C: .....

              1. Tach!

                Weißt du vllt. noch ob es eine Möglichkeit gibt beide Abfragen zu verbinden?

                Ja, mit UNION.

                SELECT h.name, COUNT(h.id)

                FROM haupt h, company c
                WHERE h.companyId = c.id
                GROUP BY h.name
                ORDER BY h.id

                SELECT COUNT(h.id)
                FROM haupt h
                WHERE h.companyId NOT IN (SELECT c.id FROM company c)

                  
                Die zweite Abfrage braucht jedoch noch einen Ersatz für das h.name-Feld der ersten Query, da sie ja jetzt nur eine Summe liefert. Das kann auch ein fester String sein.  
                  
                Desweiteren wird bei UNION die Sortierung in den einzelnen Querys ignoriert. Nur das UNION-Ergebnis kann man wirksam sortieren. Da bei dir die h.id das Kriterium ist, müsstest du das auch noch in die Ergebnismenge der ersten Query bringen und einen Pseudowert in die zweite.  
                  
                Noch was: Du gruppierst über h.name. In jeder Gruppe sind zwar alle Namen gleich, aber es sind verschiedene h.id enthalten. Welche von den vielen soll denn bei der Sortierung berücksichtigt werden. MySQL lässt sowas zwar im Gegensatz zu anderen DBMS zu, aber du bekommst nur einen beliebigen Wert aus der zur Gruppe gehörenden Menge. Nach der ID zu sortieren ist auch sinnlos, weil die Werte quer über alle Gruppen beliebig verteilt sind.  
                  
                
                > Ich hab mir gedacht den Inhalt aus dem 2. Query in den 1. Query zu schreiben den die Werte aus der DB werden ja in einem Array gespeichert.  
                > $query1[] = $query2  
                > aber bekomme dann die Fehldermeldung:  Cannot use a scalar value as an array in C: .....  
                  
                Dazu kann ich nichts sagen, weil ich nicht weiß, was in den Variablen enthalten ist. Jedenfalls ist $query1 kein Array.  
                  
                  
                dedlfix.
                
                1. Ja, mit UNION.

                  SELECT h.name, COUNT(h.id)

                  FROM haupt h, company c
                  WHERE h.companyId = c.id
                  GROUP BY h.name
                  ORDER BY h.id

                  SELECT COUNT(h.id)
                  FROM haupt h
                  WHERE h.companyId NOT IN (SELECT c.id FROM company c)

                    
                  Vielen Dank!  
                  Jetzt funktioniert alles. Das Group By und das Order By sind absichtlich so, auch wenn dies abwegig aussieht bzw. falsch. Leider ist die DB mit der ich arbeiten muss so aufgebaut das dies nötig ist. -.-
                  
      2. SELECT h.*  
        FROM haupt h, company c  
        WHERE h.companyId = c.id
        

        From haupt, company
        bedeutet, das du hier eine Multiplikation bzw. Kreuzprodukt oder auch kartesisches Produkt genannt, der beiden Tabellen bildest. Das bedeutet nach dieser Abfrage, jedes Tupel der Tabelle "haupt" wird mit jedem Ergebnistupel der Tabelle Company vereint,
        Wenn in der Tabelle Haupt 3000 Zeilen  sind und das Ergebnis aus
        companyId= c.id ca 2 Treffer hat, dann verdoppeln sich die Ergebniszeilen
        3000 x 2

        Näheres zu den verschiedenen Operationen kannst du hier nachlesen:
        http://mixst.de/index.php?thema=db2
        Es ist dort zwar in relationaler Algebra erklärt, aber die grundsätzliche Mathematik dahinter ist die gleiche
        http://mixst.de/index.php?thema=db2&men=6&submen=5

        SELECT *
        FROM haupt h, company c
        WHERE h.companyId NOT IN (SELECT h.companyId FROM haupt h, company c WHERE h.companyId = c.id)

          
        Diese Abfrage bedeutet, das du nun alle Zeilen aus "haupt" mit den Zeilen aus "company" vereinst, deren "companies" nicht in "haupt" enthalten sind.  
          
        
        
  2. Hi,

    Ich kann nur Vermutungen anstellen. Was auch immer du für ein DBMS verwendest.

    Möglicherweise hast du eine Anzeigebegrenzung irgendwo eingestellt auf 3000.
    Dann kannst du mal danch suchen und sie entweder ausschalten oder deine Arbeitsweise überdenken.

    Die Frage ist doch eigentlich was du damit bezweckst.
    Entweder du möchtest die Daten exportieren, dann gibt es bessere Methoden als den SQL Editor oder du möchtest etwas suchen, dann kannst du danach auch deine Select Anweisung begrenzen.

    lg
    apfelsine

    1. Möglicherweise hast du eine Anzeigebegrenzung irgendwo eingestellt auf 3000.

      Die Zahlen sind aufgerundet.

      Die Frage ist doch eigentlich was du damit bezweckst.

      Ich brauche die Abfragen und noch andere für eine Statistische Auswertung in PHP. Und wenn da einfach mal hunderte Einträge fehlen ist das nicht so gut.