# Aufgabe mit Aggregation und Unteranfragen



## Kirby.exe (8. Jan 2021)

Also wir haben folgende Aufgabe:



Ich hänge da gerade etwas fest 

Das hier war mein kläglicher Versuch:


```
Select count(wrk.mngr) as anz,
        (sum(salary)/count(wrk.mngr)) as min_sal

From emp e1, (Select e1.empno as mngr,
              e2.sal as salary,
              e2.job
              From emp e2
              where e1.empno = e2.mgr
              ) as wrk
```

Aber hier kommt dann diese schöne Fehlermeldung:


```
Fehler in der SQL-Abfrage (7): ERROR: invalid reference to FROM-clause entry for table "e1"
LINE 4: From emp e1, (Select e1.empno as mngr,
HINT: There is an entry for table "e1", but it cannot be referenced from this part of the query.
```

Wieso kann ich werte aus e1 nicht in die Ergebnistabelle meines Subquery stecken und wie es möglich dies zu tun?


----------



## Kirby.exe (8. Jan 2021)

Ich habe es jetzt einfach mit einem selbstverbund und aggregation gemacht, da ich den Sinn in einer Unteranfrage nicht sehe:


```
Select count(distinct e1.empno) as anz,
        min(e1.sal) as min_sal,
        max(e1.sal) as max_sal,
        round(sum(e1.sal)/count(e1.empno)) as avg_sal,
        count(distinct e1.job) as anz_jobs
From emp e1, emp e2
Where e1.empno = e2.mgr
```

Das einzige was noch nicht ganz richtig ist, avg_sal (ich sehe nicht wirklich wie die darauf kommen xD


----------



## Kirby.exe (8. Jan 2021)

Ahhhh jetzt sehe ich den Sinn in der Sub Anfrage....Damit kann ich die duplikate entferne welche ich oben in den Aggregats Anfragen unterdrücke  Das ist mein Code jetzt und er returned das gewollte Ergebnis:


```
Select count(res1.empno) as anz,
        min(res1.sal) as min_sal,
        max(res1.sal) as max_sal,
        round(sum(cast(res1.sal as decimal))/count(res1.empno)) as avg_sal,
        count(res1.job) as anz_jobs
From (Select distinct e1.empno, e1.ename, e1.job, e1.sal From emp e1, emp e2 Where e1.empno = e2.mgr) as res1
```


----------



## kneitzel (8. Jan 2021)

Also den Hinweis bezüglich JOIN wurde doch schon einmal gesagt ... ok, das in #2 is ok, aber wenn ich das aus #1 sehe, dann verzweifel ich (denn Du machst da ja nicht erst seid heute!)

Und Du willst Dir evtl. einfach die AVG Methode ansehen?

Und ein JOIN wird nicht notwendig sein, denn der Vorgesetzte ist ja egal. Da wird ja hoffentliche ein Foreign Key drauf sein, so dass Du nur eine WHERE Bedingung brauchst, dass e2.mgr nicht null ist.

Und das Ergebnis ist natürlich falsch, weil Deine Bedingung falsch ist. Du machst den avg von allen Leuten, die Vorgesetzte sind. (Also ein e2 Eintrag haben mit mgr = empno)
Edit: Das hatte ich in der Aufgabe falsch gelesen ... man will die Vorgesetzten haben ...


----------



## Meniskusschaden (10. Jan 2021)

kneitzel hat gesagt.:


> Edit: Das hatte ich in der Aufgabe falsch gelesen ... man will die Vorgesetzten haben ...


Irgendwie ist die Aufgabe doch auch einfach falsch formuliert bzw. widersprüchlich zur erwarteten Antwort:

"Betrachtet seien alle Angestellten mit Untergebenen ... Berechnen Sie für *diese* Angestellten:"

Es geht also nur um die Chefs und davon gibt es lediglich zwei (KING und JONES). Für anz müsste also eigentlich 2 heraus kommen und nicht 6. Bei den anderen Werten ist es ähnlich.


----------



## mihe7 (11. Jan 2021)

Meniskusschaden hat gesagt.:


> Irgendwie ist die Aufgabe doch auch einfach falsch formuliert bzw. widersprüchlich zur erwarteten Antwort:
> 
> "Betrachtet seien alle Angestellten mit Untergebenen ... Berechnen Sie für *diese* Angestellten:"
> 
> Es geht also nur um die Chefs und davon gibt es lediglich zwei (KING und JONES). Für anz müsste also eigentlich 2 heraus kommen und nicht 6. Bei den anderen Werten ist es ähnlich.


Unten werden nur die Angestellten mit Untergebenen gezeigt. D. h. die Tabelle aller Angestellten dürfte einfach weit größer sein 

Ich würde es einfach so verstehen:

```
SELECT count(empno) AS anz, 
    min(sal) AS min_sal, max(sal) AS max_sal, round(avg(sal), 2) AS avg_sal, 
    count(DISTINCT job) as anz_jobs
 FROM emp 
WHERE empno IN (SELECT DISTINCT mgr FROM emp WHERE mgr IS NOT NULL);
```


----------



## Kirby.exe (11. Jan 2021)

mihe7 hat gesagt.:


> Ich würde es einfach so verstehen:
> 
> ```
> SELECT count(empno) AS anz,
> ...


Es gibt fast das richtige aus xD  Der Prof möchte aber, dass man den avg() ganz rundet


----------



## mihe7 (11. Jan 2021)

Kirby_Sike hat gesagt.:


> Der Prof möchte aber, dass man den avg() ganz rundet


Aus 2 mach 0


----------



## Kirby.exe (11. Jan 2021)

mihe7 hat gesagt.:


> Aus 2 mach 0


Oder einfach weglassen xD


----------

