Verschachtelt SUM(COUNT()) ?
Paul
- datenbank
1 Vinzenz Mai0 Paul0 Vinzenz Mai0 Ilja0 Vinzenz Mai0 Ilja
Hi,
wie kann man mit SQL eine SUM und eine COUNT Funktion mit einander verschachteln?
Beispiel:
t_aussendienst, t_chef, t_innnendienst
Nun möchte ich gerne alle Gehälter jeder Tabelle zählen (count)
und anschließend diese summieren.
Quellcode:
SELECT
sum(
count(t_aussendienst.gehalt) +
count(t_chef.gehalt) +
count(t_innendienst.gehalt)
)
FROM t_aussendienst, t_chef, t_innnendienst
WHERE Gehalt > 450;
Bekomme immer Fehlermeldung: iNVALID USE OF GROUP FUNCTION
Hallo Paul,
Beispiel:
t_aussendienst, t_chef, t_innnendienst
Nun möchte ich gerne alle Gehälter jeder Tabelle zählen (count)
und anschließend diese summieren.
SELECT
sum(
count(t_aussendienst.gehalt) +
count(t_chef.gehalt) +
count(t_innendienst.gehalt)
)
FROM t_aussendienst, t_chef, t_innnendienst
WHERE Gehalt > 450;
Dir fehlen offensichtlich SQL-Grundlagen. Das Handbuch Deines DBMS sollte Dir weiterhelfen, z.B. für (das bei der GROUP-BY-Klausel schlampige) MySQL im Abschnitt http://dev.mysql.com/doc/refman/5.0/en/group-by-functions-and-modifiers.html.
Weiterhin möchtest Du keinen CROSS JOIN, sondern UNION verwenden, was alle vernünftigen Datenbankmanagementsysteme (DBMS) beherrschen, seit Version 4.0 sogar MySQL, siehe http://dev.mysql.com/doc/refman/5.0/en/union.html.
Ich empfehle Dir die Lektüre der Datenbankartikel von SELFHTML aktuell.
Freundliche Grüße
Vinzenz
Alles klar, ich werde mich noch etwas mehr informieren.
Ich danke dir ; )
Hallo Paul,
um die Kritik zu konkretisieren:
Beispiel:
t_aussendienst, t_chef, t_innnendienst
Nun möchte ich gerne alle Gehälter jeder Tabelle zählen (count)
und anschließend diese summieren.
Offensichtlich existieren Daten in drei Tabellen statt in einer. Sieht derzeit nach fehlerhaftem Datenbankdesign aus.
Nehmen wir jetzt an, Du hättest
4 Einträge in der Chefetage,
250 Einträge im Innendienst und
1000 Einträge im Außendienst.
SELECT
sum(
count(t_aussendienst.gehalt) +
count(t_chef.gehalt) +
count(t_innendienst.gehalt)
)
FROM t_aussendienst, t_chef, t_innnendienst
WHERE Gehalt > 450;
Dann hätte
SELECT
a.gehalt,
c.gehalt,
i.gehalt
FROM t_aussendienst a, t_chef c, t_innendienst
eine Million Einträge (wegen des CROSS JOINS):
Jeder Eintrag aus dem Bereich Chef wird mit jedem Eintrag aus dem Bereich Außendienst und jede dieser Kombinationen wieder mit jedem Eintrag aus dem Bereich Innendienst kombiniert.
Auf welche Spalte gehalt soll nun Deine WHERE-Klausel wirken?
Statt dessen solltest Du im ersten Schritt Dein fehlerhaftes Datenbankdesign mit einer UNION korrigieren:
SELECT
gehalt
FROM t_aussendienst
WHERE gehalt > 450
UNION ALL -- damit Du auch doppelte Werte bekommst
-- wenn zwei das gleiche verdienen.
SELECT
gehalt
FROM t_chef
WHERE gehalt > 450 -- Die WHERE-Klausel ist in jedem Einzelstatement anzugeben
UNION ALL
SELECT
gehalt
FROM t_innendienst
WHERE gehalt > 450
Kannst Du Dir jetzt die weiteren Schritte vorstellen?
Freundliche Grüße
Vinzenz
yo Vinz,
kann den mysql UNION mit GROUP BY verwenden, schließlich will er die summen bilden bzw, alle datensätze aufzählen ?
Ilja
Hallo Ilja,
kann den mysql UNION mit GROUP BY verwenden, schließlich will er die summen bilden bzw, alle datensätze aufzählen ?
wenn es nur um die Summe der Anzahl der entsprechenden Datensätze geht, benötigt Paul kein GROUP BY, sondern nur ein Subselect - und das geht mit MySQL 4.1 definitiv, das habe ich getestet.
Schritt 2 wäre bei meiner Lösung somit das Anwenden von COUNT() in den Einzelabfragen, selbstverständlich bleibt es bei UNION ALL, schließlich könnte es genausoviele Außen- wie Innendienstler geben und zum Schluss wird in
Schritt 3 die bisherige Abfrage in ein Subselect gepackt, diesem ein Alias verpaßt und außen summiert.
Geht, wie bereits erwähnt. Führt zum hoffentlich gewünschten Ergebnis.
Vielleicht gäbe es auch eine Lösung, bei der man die Werte zunächst in drei Spalten einer einzigen Zeile packt und diese dann einfach addiert, so wie dies Paul innerhalb des Aufrufs von SUM() in seinem Statement getan hatte, d.h. also doppelt aufsummieren wollte.
Über eine alternative Lösung mache ich mir allerdings keine großen Gedanken, da meine funktioniert. Außerdem finde ich sie nachvollziehbar. Grundsätzlich halte ich das Beispiel für schlecht gewählt. Vielleicht hat Paul ja ganz andere Daten, als sein Beispiel glauben läßt. In diesem Fall wiederhole ich gern: es ist sinnvoller, genau die Strukturen hier (halt mit Beispieldaten) anzugeben, bei denen das Problem auftritt.
Freundliche Grüße
Vinzenz
yo Vinz,
wenn es nur um die Summe der Anzahl der entsprechenden Datensätze geht, benötigt Paul kein GROUP BY, sondern nur ein Subselect - und das geht mit MySQL 4.1 definitiv, das habe ich getestet.
unstrittig, aber die frage war eine andere. wenn er nur die summen und die anzahl der gehälter braucht, so wie er es geschrieben hat, dann müssten man bei deiner abfrage mit den UNION ALL gruppieren. deswegen meine frage, kann mysql das ?
wenn nicht, wäre der weg über UNION ALL meiner meinung nach nicht sinnvoll, da dadruch nur die summen, bzw. anzahl der einzelnen tabellen ausgegeben würde, es sei den, man geht zusätzlich den umweg über unterabfragen. aber dann kann ich gleich auf unterabfragen gehen und mir den UNION ALL sparen.
Schritt 2 wäre bei meiner Lösung somit das Anwenden von COUNT() in den Einzelabfragen, selbstverständlich bleibt es bei UNION ALL, schließlich könnte es genausoviele Außen- wie Innendienstler geben und zum Schluss wird in
unstrittig, aber wie gesagt, hat man dadurch die summen der einzelnen tabellen. wenn ich ihn richtig verstanden haben, will er aber die ergebnisse aller drei tabellen aufsummieren.
Schritt 3 die bisherige Abfrage in ein Subselect gepackt, diesem ein Alias verpaßt und außen summiert.
umständlich, wenn mysql kein group by mit UNION ALL kann, dann würde ich gleich unterabfragen benutzen. warum dann der schritt über UNION ALL ?
Vielleicht hat Paul ja ganz andere Daten, als sein Beispiel glauben läßt. In diesem Fall wiederhole ich gern: es ist sinnvoller, genau die Strukturen hier (halt mit Beispieldaten) anzugeben, bei denen das Problem auftritt.
unstrittig
Ilja