Paul: Verschachtelt SUM(COUNT()) ?

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

  1. 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

    1. Alles klar, ich werde mich noch etwas mehr informieren.

      Ich danke dir ; )

    2. 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

      1. yo Vinz,

        kann den mysql UNION mit GROUP BY verwenden, schließlich will er die summen bilden bzw, alle datensätze aufzählen ?

        Ilja

        1. 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

          1. 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