Olaf: Keine Gruppenfunktion für Einzelgruppe !

Hallo, ich habe ein Gruppierungsproblem mit Oracle. Alle Datensätze mit der selben ID gehören zu einem Arbeitsauftrag. Dieser Auftrag wird wieder unterteilt. Die Dauer_Netto bleibt für jeden Arbeitsauftrag gleich. Nun möchte ich den gesamten Aufwand pro Arbeitsauftrag ausrechnenen und dementsprechend zuordnen (Schnell, Mittel und Langsam).

Fehlermeldung:
Keine Gruppenfunktion für Einzelgruppe !

Hoffe ihr könnt mir helfen.

SQL

SELECT
id,
dauer_netto,
COUNT(CASE WHEN sum(aufwand_der_aufgabe) <=20 THEN 1 ELSE NULL END) AS Schnell,
COUNT(CASE WHEN sum(aufwand_der_aufgabe) >20 AND sum(aufwand_der_aufgabe) <=40 THEN 1 ELSE NULL END) AS Mittel,
COUNT(CASE WHEN sum(aufwand_der_aufgabe) >40 THEN 1 ELSE NULL END) as Langsam
FROM
Table
group by id,dauer_netto

Tabelle

ID |  Dauer_Netto | Aufwand_der_Aufgabe |
001|     15       |       5             |
001|     15       |       7             |
001|     15       |       3             |
002|      x       |       X             |

  1. Hi,

    du willst (lt. deinem Eingangstext) eigentlich summieren und je nachdem was die Summe ergiebt "Schnell", "Mittel" oder "Langsam" ausgeben (respektive ein bit für die einzelnen Werte). Warum verwendest du dann COUNT?

    Dein Ergebnis soll dann so aussehen:

    ID  |  Dauer_Netto | Aufwand_der_Aufgabe |Schnell|Mittel|Langsam
    001|     15       |       15             | 1 | 0 | 0

    ?

    Dann passt aber

    002|      x       |       X             |

    nicht wirklich ins Schema? Oder? x und X kann man nicht wirklich aufsummieren.

    Warum verpackst du die Zusammenrechnung des gesamtaufwandes nicht einfach in eine Unterabfrage?

    Also, zb.

    SELECT
            -- entscheidung ob langsam, schnell, oder mittel, mit CASE aber ohne COUNT
        FROM
           (SELECT Avg(DauerNetto) AS DauerNetto,
                         Sum(Aufwand) AS AufwandTotal,
                         Count(*) AS AnzahlTeilaufträge,
                         Id
                   FROM DeineTabelle
                   Group by Id) AS summedUp

    Aufgrund der Mehrfachaufführung des identischen Wertes DauerNetto für die selbe Id spekuliere ich mal auf unzureichende Normalisierung. Dadurch das DauerNetto so denormalisiert ist, brauchst du nicht danach Gruppieren, sondern kannst einfach AVG oder Max oder Min nehmen, ergibt dann immer dasselbe. Daran siehst du schon: schlechtes Design.

    Ciao, Frank

    1. Hi Frank,

      danke für deine schnelee Antwort, jetzt bringt er aber folgenden Fehler: SQL-Befehl wurde nicht korrekt beendet.

      SELECT
         CASE WHEN sum(aufwand_der_aufgabe) <=20 THEN 1 ELSE NULL END AS Schnell,
        CASE WHEN sum(aufwand_der_aufgabe) >20 AND sum(aufwand_der_aufgabe) <=40 THEN 1 ELSE NULL END AS Mittel,
        CASE WHEN sum(aufwand_der_aufgabe) >40 THEN 1 ELSE NULL END as Langsam
          FROM
             (SELECT Avg(DAUER_NETTO) AS DauerNetto,
                           Sum(Aufwand_der_aufgabe) AS AufwandTotal,
                           Count(*) AS AnzahlTeilaufträge,
                           ID
                     FROM Table
                     Group by ID) AS summedUp

      Danke.

      1. Hi,

        fehlt dir evt. ein ; am Ende?

        Ausserdem brauchst du auch kein Sum mehr oben in CASE WHEN sum(aufwand_der_aufgabe) .... die Summe hast du ja auch schon berechnet.

        Hab leider hier kein Orakel zur Verfügung.

        Geh doch mal strukturiert an die Fehlerbeseitigung ...

        Funktioniert
        SELECT Avg(DAUER_NETTO) AS DauerNetto,
                             Sum(Aufwand_der_aufgabe) AS AufwandTotal,
                             Count(*) AS AnzahlTeilaufträge,
                             ID
                       FROM Table
                       Group by ID

        Ja? Super, nächster Schritt!

        Funktioniert
        SELECT *
            FROM
               (SELECT Avg(DAUER_NETTO) AS DauerNetto,
                             Sum(Aufwand_der_aufgabe) AS AufwandTotal,
                             Count(*) AS AnzahlTeilaufträge,
                             ID
                       FROM Table
                       Group by ID) AS summedUp

        Ja, nein, Gummibaum?
        Wenn nein, dann setze dich mit der Doku von PL/SQL auseinander, wie Subqueries syntaktisch richtig geschrieben werden.

        Wenn ja, nächster Schritt: Führ die Case-Behandlung ein.

        Einfach immer das grosse Problem in mehrere kleine (lösbarere) zerlegen.

        Ciao, Frank

  2. yo,

    nimm doch das CASE ausserhalb der aggregation.

    SELECT id, dauer_netto,
           CASE
               WHEN sum(aufwand_der_aufgabe) <=20
               THEN 'Schnell'
               WHEN sum(aufwand_der_aufgabe) BETWEEN 21 AND 40
               THEN 'Mittel'
               ELSE 'Langsam'
           END 'Laufzeit'
    FROM Table
    GROUP BY id, dauer_netto

    Ilja