simon: MySQL abfrage

Hallo,

ich hab ein kleines DB Problem.

ich hab eine DB die ca so aufgabaut ist:

xyz | 0 | xyz | xyz
xyz | 0 | xyz | xyz
xyz | 2 | xyz | xyz
xyz | 2 | xyz | xyz
xyz | 2 | xyz | xyz
xyz | 0 | xyz | xyz
xyz | 8 | xyz | xyz
xyz | 0 | xyz | xyz
...

Ich hab also eine Spalte, in der verschiedenen Zahlen (nur Ganzzahlen) stehen. Nun will ich wissen, welche dieser Zahlen in dieser Spalte am häufigsten (und wie häufig) vorkommt! Also in diesem Fall die 0 ganze 4 Mal!

Ich hab nur keinen Plan wie ich diese spezielle Abfrage realisieren kann... Jemand eine schöne Idee??

Thx

  • Simon
  1. Hallo Simon,

    versuchs mal damit.

    "select Spaltennname, count(Spaltennname) from tbTabelle group by Spaltenname"

    Spaltenname: Name der Spalte, in der die Zahlen stehen
    tbTabelle: Tabellenname

    Mit der Syntax von mySql bin ich nicht so vertraut, kann also Fehler bzgl. Hochkomma haben.

    Gru0 Jan

    Hallo,

    ich hab ein kleines DB Problem.

    ich hab eine DB die ca so aufgabaut ist:

    xyz | 0 | xyz | xyz
    xyz | 0 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 0 | xyz | xyz
    xyz | 8 | xyz | xyz
    xyz | 0 | xyz | xyz
    ...

    Ich hab also eine Spalte, in der verschiedenen Zahlen (nur Ganzzahlen) stehen. Nun will ich wissen, welche dieser Zahlen in dieser Spalte am häufigsten (und wie häufig) vorkommt! Also in diesem Fall die 0 ganze 4 Mal!

    Ich hab nur keinen Plan wie ich diese spezielle Abfrage realisieren kann... Jemand eine schöne Idee??

    Thx

    • Simon
  2. Hallo,

    ich hab ein kleines DB Problem.

    ich hab eine DB die ca so aufgabaut ist:

    xyz | 0 | xyz | xyz
    xyz | 0 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 0 | xyz | xyz
    xyz | 8 | xyz | xyz
    xyz | 0 | xyz | xyz
    ...

    Ich hab also eine Spalte, in der verschiedenen Zahlen (nur Ganzzahlen) stehen. Nun will ich wissen, welche dieser Zahlen in dieser Spalte am häufigsten (und wie häufig) vorkommt! Also in diesem Fall die 0 ganze 4 Mal!

    Ich hab nur keinen Plan wie ich diese spezielle Abfrage realisieren kann... Jemand eine schöne Idee??

    Thx

    • Simon

    Hallo Simon,

    select Zahl, count(Zahl)
    from Tabelle
    group by Zahl
    having count(Zahl)=
       (select max(anzahl)
       from
          (select Zahl, count(Chip) as anzahl
          from Tabelle
          group by Zahl)
       )
    ;

    So, die innerste Abfrage holt die mal die Zahlen und wie oft sie vorkommen. Die darueber liegende Abfrage benutzt diese Ergebnismenge der inneren Abfrage als Tabelle und sucht die Maimalzahl. Bei mehreren gleich großen Zahlen wird nur eine dieser Zahlen zurueckgeliefert. Und das ist wichtig, weil die aeusserste Abfrage eine "=" und keine "in"-Beziehung ist. Die aeusserste Abfrage sucht also alle Zahlen, zaehlt wie oft sie vorkommt (group by) und fuer diese Ergebnismenge muss der count gleich dem Ergebnis der inneren Abfrage sein. Dadurch erhaelst Du die Zahl, die am Haeufigsten vorkommt und gleichzeitig, wie oft.

    Gruß

    Hans

    1. Ersetze "Chip" durch "Zahl"

      Gruß

      Hans

    2. Hallo Hans,

      ich behauptete nicht umsonst, dass (in MySQL)

        
      
      > select Zahl, count(Zahl)  
      > from Tabelle  
      > group by Zahl  
        
      -- das da:  
        
      
      > having count(Zahl)=  
      >    (select max(anzahl)  
      >    from  
      >       (select Zahl, count(Zahl) as anzahl  
      >       from Tabelle  
      >       group by Zahl)  
      >    )  
        
      -- komplizierter ist als ein einfaches  
        
      LIMIT 1  
      
      

      Andere DBMS, z.B. MS SQL-Server unterstützen eine TOP-Klausel und bei Oracle könnte man etwas mit rowcount() o.ä. zaubern. Nur bei MySQL musst Du halt berücksichtigen, dass Subselects erst mit 4.1.x eingeführt wurden und deswegen nicht vorausgesetzt werden können. Möglicherweise ist LIMIT in diesem Fall auch performanter als die technisch sauberere Subselect-Version.

      Freundliche Grüße

      Vinzenz

      1. yo,

        Möglicherweise ist LIMIT in diesem Fall auch performanter als die technisch sauberere Subselect-Version.

        LIMIT kann aber nur zum einsatz kommen, wenn ihm ein datensatz reicht. es können aber durchaus mehr als einer sein....

        Ilja

        1. Hallo Ilja,

          Möglicherweise ist LIMIT in diesem Fall auch performanter als die technisch sauberere Subselect-Version.

          LIMIT kann aber nur zum einsatz kommen, wenn ihm ein datensatz reicht. es können aber durchaus mehr als einer sein....

          ja, Du hast recht. Das habe ich nicht bedacht :-( Was für ein Glück, dass ich wenigstens von der technisch saubereren Lösung gesprochen habe ...

          Freundliche Grüße

          Vinzenz

          1. Ich glaube mein anderes Post wird leicher übersehen...

            Hallo an alle,

            besten Dank ersteinmal an alle!
            Ich habe es nun so versucht:

            SELECT wert, count(wert) FROM tabelle GROUP BY wert LIMIT 1

            x | 6 | y | z
            x | 1 | y | z
            x | 1 | y | z
            x | 1 | y | z
            x | 1 | y | z
            x | 5 | y | z
            x | 5 | y | z
            x | 4 | y | z
            x | 1 | y | z
            x | 9 | y | z

            Jedoch ist das irgendwie noch nicht richtig.

            1. bekomme ich die Gesamtanzahl der Einträge (also im Bsp. 10 anstatt 5 (5 = Häufigkeit der am häufigsten auftretenden Zahl(1))
            2. liefert wert nicht die zahl die am häufigsten auftritt...? (also im Bsp 1)

            Wie muß ich das nun noch ändern?
            Mir würde es reichen, wenn mehrere gleich häufig auftreten das ich einen zurückgegeben bekomme...

            Vielen Dank jedenfalls schon mal!

            Gruss

            • Simon
            1. Hallo Simon,

              SELECT wert, count(wert) FROM tabelle GROUP BY wert LIMIT 1

              Also gehe ich davon aus, dass die zu untersuchende Spalte den Namen "wert" trägt.

              Jedoch ist das irgendwie noch nicht richtig.

              1. bekomme ich die Gesamtanzahl der Einträge (also im Bsp. 10 anstatt 5 (5 = Häufigkeit der am häufigsten auftretenden Zahl(1))
              1. liefert wert nicht die zahl die am häufigsten auftritt...? (also im Bsp 1)

              Du hast mein Posting nicht aufmerksam genug gelesen:

              Sortiere absteigend nach Häufigkeit mit ORDER BY ... DESC.

              stand da. Damit ist im ersten Datensatz derjenige mit der höchsten Anzahl.

              SELECT  
                wert,  
                count(wert) AS anzahl  -- ein netter Spaltenname ist doch schöner :-)  
              FROM tabelle  
              GROUP BY wert  
              ORDER BY anzahl DESC     -- nach Anzahl absteigend sortieren  
              LIMIT 1                  -- nur den ersten Wert ausgeben, dieser hat die  
                                       -- grösste Anzahl. Vorsicht: Nicht eindeutig!  
              
              

              Freundliche Grüße

              Vinzenz

              1. Hi Vinzenz,

                ne ne, die Spalte heißt natürlich nicht wert ;)
                Habs ausprobiert, leider geht es irgendwie immernoch nicht!

                SELECT eingetragenvon, count(eingetragenvon) AS anzahl FROM $tabelle_kontakte GROUP BY eingetragenvon ORDER BY anzahl DESC LIMIT 1

                Bekomme nun eingetragenvon = 0 und anzahl = 26.
                Wobei das nicht stimmt. Es sind insgesammt 26 Datensätze in der Tabelle.  12 mal steht in eingetragenvon 0 und 14 mal steht in eingetragenvon 35. Sprich, eigentlich müßte die Abfrage eingetragenvon = 35 und anzahl = 14 ausspucken!

                Was mach ich falsch?
                Danke für deine Mühe!

                • Simon
                1. Hallo Simon,

                  SELECT eingetragenvon, count(eingetragenvon) AS anzahl FROM $tabelle_kontakte GROUP BY eingetragenvon ORDER BY anzahl DESC LIMIT 1

                  Was mach ich falsch?

                  Das weiß ich nicht. Meine Glaskugel ist leider immer noch etwas trübe ;-) Aber ein paar Tipps zum Debugging. Meine Glaskugel meinte, dass Du PHP zum Zusammenbauen Deines SQL-Statements nutzt. Du solltest Dir auf jeden Fall einmal das Statement so anzeigen lassen, wie es an die Datenbank geschickt wird.

                  Weiter: Baue Deine Anweisung Schritt für Schritt zusammen. Dann verstehst Du auch besser, was passiert:

                  1. Schritt: Welche Werte stehen in der Spalte "eingetragenvon"

                  SELECT  
                    eingetragenvon  
                  FROM Tabelle
                  

                  2. Schritt: Gruppiere nach den verschiedenen Werten

                  SELECT  
                    eingetragen  
                  FROM Tabelle  
                  GROUP BY eingetragenvon
                  

                  3. Schritt: Füge die Anzahl hinzu

                  SELECT  
                    eingetragenvon,  
                    count(eingetragenvon)  
                  FROM Tabelle  
                  GROUP BY eingetragenvon
                  

                  4. Schritt: Gebe der Spalte Anzahl einen vernünftigen Namen

                  SELECT  
                    eingetragenvon,  
                    count(eingetragenvon) AS anzahl  
                  FROM Tabelle  
                  GROUP BY eingetragenvon
                  

                  5. Schritt: Sortiere nach Anzahl absteigend

                  SELECT  
                    eingetragenvon,  
                    count(eingetragenvon) AS anzahl  
                  FROM Tabelle  
                  GROUP BY eingetragenvon  
                  ORDER BY anzahl DESC
                  

                  6. Schritt: Limitiere das Ergebnis auf den ersten Datensatz

                  SELECT  
                    eingetragenvon,  
                    count(eingetragenvon) AS anzahl  
                  FROM Tabelle  
                  GROUP BY eingetragenvon  
                  ORDER BY anzahl DESC  
                  LIMIT 1
                  

                  Prinzipiell gesehen müsste schon der erste Schritt ein von Dir nicht erwartetes Ergebnis liefern. Du darfst gern die Ausgabe dieser Abfragen posten (vielleicht nicht gerade das Ergebnis des ersten Schritts, das solltest Du eher beschreiben). Ach ja, grundsätzlich interessiert mich bei MySQL stets die genaue Versionsnummer.

                  Freundliche Grüße

                  Vinzenz

                  1. Hi Vinzenz,

                    besten Dank erneut. Ich habs nun gelöst bekommen! Es lang an den Werten in der Datenbank. Die hatte ich nich nocheinmal überprüft...

                    Vielen Dank für deine Hilfe!!!
                    Auch an alle anderen.

                    • Simon
  3. Hallo Simon,

    Spaltennamen wären ganz nett.

    xyz | 0 | xyz | xyz
    xyz | 0 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 2 | xyz | xyz
    xyz | 0 | xyz | xyz
    xyz | 8 | xyz | xyz
    xyz | 0 | xyz | xyz
    ...

    Ich hab also eine Spalte, in der verschiedenen Zahlen (nur Ganzzahlen) stehen. Nun will ich wissen, welche dieser Zahlen in dieser Spalte am häufigsten (und wie häufig) vorkommt! Also in diesem Fall die 0 ganze 4 Mal!

    Du möchtest also, gruppiert nach den Werten, zählen, wie oft ein Eintrag vorkommt - limitiert auf den mit dem häufigsten Vorkommen?

    => Verwende GROUP BY in Verbindung mit der Aggregatsfunktion COUNT().

    Sortiere absteigend nach Häufigkeit mit ORDER BY ... DESC.
    Limitiere das Ergebnis mit der LIMIT-Klausel.

    Die resultierende Abfrage dürfte von jeder MySQL-Version unterstützt werden.  Es gibt auch noch andere Lösungswege, die jedoch komplizierter sind.

    Freundliche Grüße

    Vinzenz

    1. Hallo an alle,

      besten Dank ersteinmal an alle!
      Ich habe es nun so versucht:

      SELECT wert, count(wert) FROM tabelle GROUP BY wert LIMIT 1

      x | 6 | y | z
      x | 1 | y | z
      x | 1 | y | z
      x | 1 | y | z
      x | 1 | y | z
      x | 5 | y | z
      x | 5 | y | z
      x | 4 | y | z
      x | 1 | y | z
      x | 9 | y | z

      Jedoch ist das irgendwie noch nicht richtig.

      1. bekomme ich die Gesamtanzahl der Einträge (also im Bsp. 10 anstatt 5 (5 = Häufigkeit der am häufigsten auftretenden Zahl(1))
      2. liefert wert nicht die zahl die am häufigsten auftritt...? (also im Bsp 1)

      Wie muß ich das nun noch ändern?
      Mir würde es reichen, wenn mehrere gleich häufig auftreten das ich einen zurückgegeben bekomme...

      Vielen Dank jedenfalls schon mal!

      Gruss

      • Simon
  4. yo,

    Ich hab also eine Spalte, in der verschiedenen Zahlen (nur Ganzzahlen) stehen. Nun will ich wissen, welche dieser Zahlen in dieser Spalte am häufigsten (und wie häufig) vorkommt! Also in diesem Fall die 0 ganze 4 Mal!

    falls dir nur ein datensatz als rückgabewert reicht, der die maximale anzahl enthält, dann geht es recht einfach:

    SELECT spalte, COUNT(*) AS anzahl
    FROM tabelle
    GROUP BY spalte
    ORDERY BY 2
    LIMIT 0,1

    falls du alle datensätze mit der höchsten anzahl haben willst, dann sollte folgendes zum einsatz kommen:

    SELECT tab1.spalte, COUNT(*) AS anzahl
    FROM tabelle AS tab1
    GROUP BY tab1.spalte
    HAVING anzahl =
       (
        SELECT MAX(COUNT(*)) FROM tabelle AS tab2 GROUP BY tab2.spalte
       )

    Ilja