Vinzenz Mai: MySQL - Join auf temporären View

Beitrag lesen

Hallo

Ohne Angabe gehe ich von einer aktuellen Produktionsversion, 5.0.x, aus.
richtig, wobei es auf allen neueren Versionen funktionieren sollte...

was verstehst Du unter einer neueren Version?
Teste unter der entsprechenden Version :-)

Join gut und schön, aber auf was? Die selbe table?

Fast. Sowas nennt man übrigens einen Selfjoin.

Wäre schön, wenn du mir ne Richtung geben könntest.

Du benötigst doch die Angabe, wie oft eine Gruppe vorkommt. Richtig? Wie Dir bereits gesagt wurde, ist es zwingend erforderlich, dass bei Verwendung einer Aggregatsfunktion über alle Spalten gruppiert (mit der GROUP-BY-Klausel) wird, auf die *keine* Aggregatsfunktion angewandt wird.

MySQL ist in dieser Hinsicht etwas schlampig und wendet auf die Spalten, auf die der schlampige Statement-Ersteller keine Aggregatsfunktion angewandt hat die Aggregatsfunktion

zufall(nicht gruppierte spalte)

an. Sofern innerhalb der Gruppe stets gleiche Werte in dieser Spalte stehen, kommt sogar das gewünschte Ergebnis heraus. Aber das nur nebenbei, das hat mit Deinem Problem nur indirekt zu tun.

Wie bekommst Du die Angabe, wie oft die Gruppen auftreten? Das geht bei den Daten aus Malcolms Beispiel mit [1]

  
SELECT                    -- Gib mir  
    gruppe,               -- die Gruppen  
    COUNT(gruppe) anzahl  -- und die Anzahl ihres Auftretens, die unter dem  
                          -- netteren Aliasnamen anzahl ausgegeben werden soll  
FROM                      -- aus  
    tabelle               -- meiner Tabelle "tabelle"  
GROUP BY                  -- gruppiert nach  
    gruppe                -- der Spalte gruppe, d.h. je Gruppe gibt es genau  
                          -- einen, den gewünschten Wert  

liefert:

gruppe | anzahl
---------------
   1   |    1
   3   |    3
   6   |    2
   8   |    1

Das hättest Du ja bestimmt selbst hinbekommen.

Für jeden Datensatz aus Deiner Ausgangstabelle benötigst Du nun den passenden Wert aus dieser Abfrage, d.h. den Wert aus anzahl für den die Gruppen übereinstimmen. Ganz logisch, das ist ein Join. Also musst Du die Ausgangstabelle mit dieser Abfrage (als temporären View) hier joinen:

SELECT                        -- Gib mir  
    t.id                      -- die id,  
    t.gruppe                  -- die zugehörige Gruppe  
    v.anzahl                  -- und die Anzahl ihres Auftretens  
FROM                          -- aus der Tabelle  
    tabelle t                 -- "tabelle", angesprochen über den Alias "t",  
INNER JOIN (                  -- die mit folgender Abfrage  
    SELECT                    --  
        gruppe,               -- temporärer View (Definition siehe oben)  
        COUNT(gruppe) anzahl  
    FROM  
        tabelle  
    GROUP BY  
        gruppe  
    ) v                       -- die über den zwingend erforderlichen Alias  
                              -- "v" angesprochen wird  
ON                            -- über die Spalten  
    t.gruppe = v.gruppe       -- gruppe beider "Tabellen" verknüpft ist  
ORDER BY                      -- sortiert nach  
    v.anzahl DESC             -- der Anzahl des Auftretens, absteigend  

hat als Ergebnismenge:

id | gruppe | anzahl
--------------------
 5 |    3   |    3
 1 |    3   |    3
 7 |    3   |    3
 6 |    6   |    2
 3 |    6   |    2
 4 |    8   |    1
 2 |    1   |    1

Beachte, dass die Reihenfolge innerhalb einer Gruppe mit einer bestimmten Anzahl zufällig ist. Möchtest Du dort eine vorgegebene Reihenfolge haben, so musst Du auch danach sortieren (als zweite, dritte, ... Sortierspalte).

Getestet unter MS SQL-Server 2005, hab' gerade kein MySQL zur Hand.

Freundliche Grüße

Vinzenz

[1] Hi Malcolm, Du lernst schnell. Und verstehst vielleicht auch besser,
    warum ich in solchen Fällen gerne nach einem Beispiel mit Beispieldaten
    frage. Es macht das Verständnis viel einfacher.