kostenloser Webspace werbefrei: lima-city


SQL Group by nicht verstanden

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    mprev

    mprev hat kostenlosen Webspace.

    Hallo Vl könnt ihr mir helfen ein SQL Statement zu verstehen:

    Ich habe da 3 Tabellen
    Lieferer
    Artikel
    Prüfer
    Sieh Unten

    Davon möchte ich jetzt in einem SQL Statement alle Lieferer (von diesen IdNr & Namen) haben,
    die Artikel von allen Prüfern haben

    Die Abfrage funktioniert:

    SELECT Lieferer.idnr, Lieferer.name
    FROM Lieferer, Artikel
    WHERE Lieferer.idnr = Artikel.idnr
    GROUP BY Lieferer.name, Lieferer.idnr
    HAVING Count(Lieferer.idnr)=4


    (die 4 kann mana uch durch ein Subselect machen, aber das ist hier nicht das wichtige)

    Allerdings verstehe ich nicht, wieso ich in dem GROUP BY beide brauche … wenn ich eines weglasse stimmt es nicht mehr.

    Tabellen:
    Lieferer
    IDNR 	KENNZAHL 	NAME
    1234567 	810 	Maier 	
    1234568 	754 	Bauer
    2345617 	754 	Müllner
    1234569 	710 	Lehner	
    3456712 	810 	Hofer	
    1234561 	752 	Schmied	
    1234560 	752 	Bäcker
    4567891 	754 	Fischer
    5678901 	710 	Lech


    Artikel
    PRUEFNUMMER	IDNR	 	NAME
    01 		1234567 	WET 			
    01 		2345617 	WET1 			
    01 		3456712 	WET2			
    02 		2345617 	Substitubsi 	
    02 		1234561 	Globale Netze 	
    02 		5678901 	Globale Netze 	
    02 		4567891 	Substitubsi 	
    03 		4567891 	Waltzwerk 		
    03 		5678901 	Waltzwerk 		
    03 		1234561 	Artikel kalr1 	
    03 		2345617 	Netzwerke 		
    04 		2345617 	Artikel klar2	
    04 		1234561 	Kabelsammlung 	
    04 		4567891 	Kabelsammlung 	
    04 		3456712 	Transformator


    Pruefer
    PRUEFNUMMER 	NAME
    01 		Maisner
    02 		Stiegl
    03 		Waller
    04 		Diedl


    Ergebniss
    IdNr		Name
    2345617 	Müllner

  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hallo mprev,

    in Standard-SQL wäre es folgendermaßen:
    Sobald eines der im SELECT-Statement ausgewählten Felder ein Aggregat, d.h. ein berechnetes Feld (MIN(), MAX(), COUNT(), AVG(), SUM(), ...), ist müssen alle Felder, die kein Aggregat sind, in der GROUP-BY-Klausel aufgelistet werden. Wenn keine Aggregate ausgewählt sind aber eine GROUP-BY-Klausel existiert, dann müssen dort alle gewählten Felder aufgelistet sein.
    Normalerweise ist es nicht zulässig ein oder mehrere Nicht-Aggregat-Felder auszulassen, da das keinen Sinn macht.
    Wäre es zulässig ein Feld auszulassen, dann können in einem solchen Fall alle Aggregatfunktionen nur auf einen Datensatz angewendet werden, da bezüglich der nicht gruppierten Felder keine Zusammenfassung stattfinden kann, auch wenn sie den selben Wert enthalten.
    Ich entnehme Deinem Posting jetzt mal, dass sowas unter MySQL zulässig ist.
    Dann führt das dazu, dass Du anstelle von einem Datensatz mit Count(Lieferer.idnr)=4 vier Datensätze mit jeweils Count(Lieferer.idnr)=1 bekommst, was dann natürlich der HAVING-Klausel widerspricht.
  4. Autor dieses Themas

    mprev

    mprev hat kostenlosen Webspace.

    Ich merke mir ist hier noch einiges mit GROUP BY unklar.

    darkpandemic schrieb:
    in Standard-SQL wäre es folgendermaßen:
    Sobald eines der im SELECT-Statement ausgewählten Felder ein Aggregat, d.h. ein berechnetes Feld (MIN(), MAX(), COUNT(), AVG(), SUM(), ...), ist müssen alle Felder, die kein Aggregat sind, in der GROUP-BY-Klausel aufgelistet werden. Wenn keine Aggregate ausgewählt sind aber eine GROUP-BY-Klausel existiert, dann müssen dort alle gewählten Felder aufgelistet sein.


    Das verstehe ich nicht. Ich dachte (oder stellte es mir so vor) das bei einem GROUP-BY
    und der Angabe einer Spalte(column) die Elemente gruppiert werden.
    So dass jene Zeilen(row) die eine Gleichen Wert haben zusammen in einer Gruppe sind.

    darkpandemic schrieb:
    Normalerweise ist es nicht zulässig ein oder mehrere Nicht-Aggregat-Felder auszulassen, da das keinen Sinn macht.
    Wäre es zulässig ein Feld auszulassen, dann können in einem solchen Fall alle Aggregatfunktionen nur auf einen Datensatz angewendet werden, da bezüglich der nicht gruppierten Felder keine Zusammenfassung stattfinden kann, auch wenn sie den selben Wert enthalten.

    Aber wieso sind die dann nicht gruppiert, das verstehe ich wohl nicht?
    Oder werden nicht die gesamten Zeilen (row) sondern jeweils nur die Werte einer Spalte gruppiert?


    darkpandemic schrieb:
    Ich entnehme Deinem Posting jetzt mal, dass sowas unter MySQL zulässig ist.
    Dann führt das dazu, dass Du anstelle von einem Datensatz mit Count(Lieferer.idnr)=4 vier Datensätze mit jeweils Count(Lieferer.idnr)=1 bekommst, was dann natürlich der HAVING-Klausel widerspricht.

    Ob es auf MySQL zulässig ist wüste ich nicht. Obiges Beispiel läuft auf Oracle (Version k.a.).
    Aber wenn ich 4 mit 1 erhalte müsste das Result leer sein, nicht Falsch oder?

    Aber cih dachte ben, dass mit einem einfachn Grouping das schon die Zusammengehörenden zusammen gegrouped sind. Und der Count dann in diesen ausgewertet wird.

  5. Hallo mprev,

    mprev schrieb:
    ... Ich dachte (oder stellte es mir so vor) das bei einem GROUP-BY
    und der Angabe einer Spalte(column) die Elemente gruppiert werden.
    So dass jene Zeilen(row) die eine Gleichen Wert haben zusammen in einer Gruppe sind.
    ...
    ich habe gerade mit SQLite rumgespielt und da ist es tatsächlich so, wie Du es sagst. Allerdings hatte ich auch schon Datenbanken bei denen es anders war. Es scheint so zu sein, dass das überall etwas anders gehandhabt wird. Hier habe ich die Doku zum Oracle GROUP BY. Dort steht allerdings, dass es so ist, wie ich es oben beschriebe habe. Insbesondere:

    All the columns used besides the aggregate functions must be included in the GROUP BY clause.

    D.h. wenn die GROUP-BY-Auflistung unvollständig ist, dann hätte die Abfrage eigentlich gar nicht ausgeführt werden dürfen sondern stattdessen ein Fehler auftreten müssen.
    Das sich das bei Dir anders verhält wundert mich jetzt ein bisschen. Aber Du kannst ja mal in der mitgelieferten Doku nachschauen, was dort zum Thema steht.
    Eine Sache ist mir noch aufgefallen. Im ersten Posting schreibst Du:
    mprev schrieb:
    ...
    Davon möchte ich jetzt in einem SQL Statement alle Lieferer (von diesen IdNr & Namen) haben,
    die Artikel von allen Prüfern haben
    ...,
    Deine Abfrage wählt aber alle Lieferer aus, denen genau vier Artikel zugeordnet sind.
    Wenn Du alle Lieferer haben willst, die mit allen Prüfern zu tun haben, dann musst Du das wie folgt machen:
    SELECT lieferer.name, lieferer.idnr
    FROM lieferer INNER JOIN 
            (SELECT DISTINCT artikel.idnr , artikel.pruefnummer 
            FROM artikel) AS subq 
         ON lieferer.idnr = subq.idnr
    GROUP BY lieferer.name, lieferer.idnr
    HAVING COUNT(lieferer.idnr) = (SELECT COUNT(pruefer.name) FROM pruefer);
    Damit wird auf die Anzahl der zugeordneten Prüfer anstatt der Anzahl der Artikel geprüft.
  6. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!