Treziman: Mehrere unterschiedliche Ergebnisse aus einer DB lesen

Hallo allerseits,
ich habe folgendes Problem, zu dem ich noch keine passende Lösung gefunden habe. Ich hoffe, hier einen Denkanstoss zu bekommen.
Es geht darum, aus EINER DB die unterschiedlichen Einträge EINER Spalte auszulesen. Die einzelnen Abfragen würden so lauten:

  
$abfrage1 = mysql_query("select count(id) from tabelle where ball = 'rot' ");  
$abfrage2 = mysql_query("select count(id) from tabelle where ball = 'blau' ");  
$abfrage3 = mysql_query("select count(id) from tabelle where ball = 'grün' ");  

Wie kann man diese Abfragen zu EINER verbinden? Über mehrere Tabellen würde es mit join gehen, aber bei nur einer Tabelle funktioniert das nicht.
Ich hätte gern sowas in der Art:

  
$abfrage = mysql_query("select count(id) as anz1 from tabelle where ball = 'rot' AND select count(id) as anz2 from tabelle where ball = 'blau' AND ...usw. ")  

Kann mir jemand auf die Sprünge helfen? Danke schonmal!

  1. Tach!

    select count(id) from tabelle where ball = 'rot'
    select count(id) from tabelle where ball = 'blau'
    select count(id) from tabelle where ball = 'grün'

    
    > Wie kann man diese Abfragen zu EINER verbinden?  
      
    Gruppieren. Mit WHERE ball IN (..., ..., ...) die gewünschten Farben wählen (falls erforderlich) und dann GROUP BY ball. ball auch noch in die SELECT-Klausel aufnehmen, sonst weist du nicht, welcher Wert zu welcher Farbe gehört.  
      
    Übrigens ist bei einem Datenbank-Problem der PHP-Code völlig uninteressant. Lass den ganz weg, dann klappt auch die Syntax-Einfärbung.  
      
      
    dedlfix.
    
    1. Hi dedlfix,
      danke für deine Antwort.
      Also ich bin jetzt soweit:

        
      select ball,count(id) from tabelle where ball in ('rot','blau','grün') group by ball  
      
      

      Das klappt so natürlich nicht. Wie frage ich denn jetzt ab, wieviele rote, blaue und grüne Bälle es gibt? Das muss doch ungefähr so aussehen:

        
      echo 'rot = '.count(rot);  
      
      
      1. Tach!

        select ball,count(id) from tabelle where ball in ('rot','blau','grün') group by ball

          
        Das ergibt eine Ergebnismenge mit zwei Spalten und drei Zeilen.  
          
        
        > Das klappt so natürlich nicht. Wie frage ich denn jetzt ab, wieviele rote, blaue und grüne Bälle es gibt?  
          
        Indem du die drei Zeilen der Ergebnismenge holst und auf die jeweils zwei Werte zugreifst. Das machst du wie bei jeder anderen Ergebnismenge auch, wofür es genügend Anleitungen gibt. Zum besseren Komfort kannst du der zweite Spalte einen Alias-Namen geben. Hilfreich sind auch hier mal wieder Kontrollausgaben. Lass dir anzeigen, was die Fetch-Funktion für ein Ergebnis liefert, dann findest du üblicherweise auch heraus, wie darauf zuzugreifen ist.  
          
          
        dedlfix.
        
        1. Indem du die drei Zeilen der Ergebnismenge holst und auf die jeweils zwei Werte zugreifst. Das machst du wie bei jeder anderen Ergebnismenge auch, wofür es genügend Anleitungen gibt.

          Klingt nach einem array.
          Also, ich habe jetzt gemacht:

            
          $menge = mysql_fetch_row($abfrage);  
          echo $menge[0]; //= 'rot' = richtig  
          echo $menge[1]; //= 2 = auch richtig  
          echo $menge[2]; // nix mehr, müsste doch eigentlich 'blau' anzeigen, oder?  
          
          

          Zum Testen habe ich in der Tabelle 2 rote und einen blauen Ball. Aber von den blauen wird nix angezeigt. Wo liegt mein Fehler?
          $menge = mysql_fetch_array($abfrage); liefert übrigens dasselbe.

          1. Tach!

            Indem du die drei Zeilen der Ergebnismenge holst und auf die jeweils zwei Werte zugreifst. Das machst du wie bei jeder anderen Ergebnismenge auch, wofür es genügend Anleitungen gibt.
            Klingt nach einem array.
            Also, ich habe jetzt gemacht:

            $menge = mysql_fetch_row($abfrage);
            echo $menge[0]; //= 'rot' = richtig
            echo $menge[1]; //= 2 = auch richtig
            echo $menge[2]; // nix mehr, müsste doch eigentlich 'blau' anzeigen, oder?

              
            Die Kontrollausgabe dazu lautet print\_r($menge) oder auch var\_dump($menge). Wie du sehen wirst, hast du nur zwei Werte.  
              
            
            > Zum Testen habe ich in der Tabelle 2 rote und einen blauen Ball. Aber von den blauen wird nix angezeigt. Wo liegt mein Fehler?  
              
            Lies bitte noch einmal den ersten Satz im obigen Zitat meiner vorhergehenden Antwort. Die Fetch-Funktionen holen immer nur eine Zeile. Du musst solange fetchen, bis kein Ergebnis mehr kommt. Das Ergebnis in nur einer Zeile zu bekommen ist möglich aber wesentlich aufwendiger als die GROUP-BY-Lösung.  
              
              
            dedlfix.
            
            1. Du musst solange fetchen, bis kein Ergebnis mehr kommt.

              Ja klar! Manchmal ist man.....

                
              while ($menge = mysql_fetch_row($abfrage))  
              {  
              echo $menge[0]. " = ".$menge[1]."<br>";  
              }  
              
              

              klappt endlich.

              Danke dedlfix! Wieder was gelernt! Solch eine kombinierte Abfrage habe ich nämlich noch nie gemacht, ausser mit join, dann aber auch über mehrere Tabellen.

              Nochmals danke.

              Gruss
              Treziman

    2. Moin!

      Gruppieren. Mit WHERE ball IN (..., ..., ...) die gewünschten Farben wählen (falls erforderlich) und dann GROUP BY

      Dieses "IN" habe ich noch nie gesehen. Kannst du mir bitte sagen, wo im deutschen Manual dazu was steht? Ich finde nichts. Danke!

      Onkel Hans

      1. Tach!

        Dieses "IN" habe ich noch nie gesehen. Kannst du mir bitte sagen, wo im deutschen Manual dazu was steht?

        Unter Functions and Operators sind sie alle aufgelistet. Die deutsche Version des Handbuchs ist aber anscheinend einmal übersetzt und dann nie wieder angefasst worden. Das Original weicht mittlerweile teilweise recht erheblich davon ab. So fehlt zum Beispiel die Übersichtsseite mit der Referenz aller Funktionen und Operatoren. Das IN() findet man unter den Vergleichsoperatoren.

        dedlfix.

  2. hi,

    Wie kann man diese Abfragen zu EINER verbinden? Über mehrere Tabellen würde es mit join gehen, aber bei nur einer Tabelle funktioniert das nicht.

    Du kannst eine Tabelle mehrfach mit sich selbst joinen. In Deinem Fall würde das Ergebnis drei Werte in einer Zeile liefern. Willste?

    Horst Willig

    --
    Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
    1. Tach!

      Wie kann man diese Abfragen zu EINER verbinden? Über mehrere Tabellen würde es mit join gehen, aber bei nur einer Tabelle funktioniert das nicht.

      Du kannst eine Tabelle mehrfach mit sich selbst joinen. In Deinem Fall würde das Ergebnis drei Werte in einer Zeile liefern. Willste?

      Man kann auch ein SELECT ohne weitere Klauseln und darin viele kleine Subselects für jeden einzelnen Wert in der Feldliste ausführen. Das ist aber alles reichlich umständlich und mit jeder neuen Farbe massiv zu erweitern. GROUP BY und Fetchen in einer Schleife ist jetzt und in Zukunft deutlich weniger Programmieraufwand und damit mit weniger potentiellen Fehlerquellen versehen.

      dedlfix.

      1. hi,

        Wie kann man diese Abfragen zu EINER verbinden? Über mehrere Tabellen würde es mit join gehen, aber bei nur einer Tabelle funktioniert das nicht.

        Du kannst eine Tabelle mehrfach mit sich selbst joinen. In Deinem Fall würde das Ergebnis drei Werte in einer Zeile liefern. Willste?

        Man kann auch ein SELECT ohne weitere Klauseln und darin viele kleine Subselects für jeden einzelnen Wert in der Feldliste ausführen. Das ist aber alles reichlich umständlich und mit jeder neuen Farbe massiv zu erweitern. GROUP BY und Fetchen in einer Schleife ist jetzt und in Zukunft deutlich weniger Programmieraufwand und damit mit weniger potentiellen Fehlerquellen versehen.

        Schade. Gerade der Join wäre so richtig interessant gewesen. Ich denke, dass auch Joins eine Zukunft haben und wer aus Fehlern lernen kann, darf auch welche machen.

        Horst

        --
        Wenn Du keine Antwort auf Deine Frage bekommst, könnte es sein, dass Du die falsche Frage gestellt hast.
        1. Schade. Gerade der Join wäre so richtig interessant gewesen. Ich denke, dass auch Joins eine Zukunft haben und wer aus Fehlern lernen kann, darf auch welche machen.

          Ich bin gespannt, ob relationale Datenbank in _ferner_ Zukunft überhaupt noch eine Rolle spielen. Dokument-Orientiert ist ziemlich hip zur Zeit. Mag auch an meiner Vorbelastung durch Node.js liegen. Ich möchte keine Prognose abgeben, aber kann mir so einige Szenarien ausmalen.

          1. Schade. Gerade der Join wäre so richtig interessant gewesen. Ich denke, dass auch Joins eine Zukunft haben und wer aus Fehlern lernen kann, darf auch welche machen.

            Ich bin gespannt, ob relationale Datenbank in _ferner_ Zukunft überhaupt noch eine Rolle spielen. Dokument-Orientiert ist ziemlich hip zur Zeit. Mag auch an meiner Vorbelastung durch Node.js liegen. Ich möchte keine Prognose abgeben, aber kann mir so einige Szenarien ausmalen.

            He mein Lieber,

            Du bist auch ein Tüftler, das habe ich auf Deinem Blog gesehen (Stichwort HTTP/PUT, erstklassiger Artikel!).

            Es gibt keinen Stillstand in der Entwicklung und diese ewigen 'Du erfindest das Rad neu...'-Nörgler kotzen mich schon lange an.

            Ich wäre kein Entwickler, wenn ich davon ausgehen würde, dass alle Räder der Welt schon erfunden sind und nicht mindestens eines dieser Räder neue Reifen gebrauchen könnte.

            Interessant ist das Entity-Attribute-Value-Model, ich schreibe gerade einen Artikel darüber auf meinen Blog (ist noch nicht fertig, coming soon...)

            EAV lässt sich auch in einer DB implementieren, das habe ich bei Magento gesehen. Diesbezügliche Gedanken hatte ich jedoch auch schon vorher und hab das auch schon praktisch in Gebrauch ;)

            Nicht nörgeln oder Ideen von vornherein zum Tode verurteilen, einfach mal machen.

            "Das Schönste, was wir erleben können, ist das Geheimnisvolle. Es ist das Grundgefühl, das an der Wiege von wahrer Kunst und Wissenschaft steht."

            Albert Einstein (1870-1955)

            Horst Ketzer

            --
            Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.