25_SQL. Klauzula GROUP BY

Do omówienia klauzuli GROUP BY skorzystamy z bezpłatnej bazy Oracle HR dostępnej tutaj:

http://www.oracle.com/technetwork/database/express-edition/downloads/index.html

 Klauzula GROUP_BY jest jedną z najważniejszych narzędzi przy raportowaniu za pomocą języka zapytań SQL Oracle. 

Z połączenia dwóch tabel EMPLOYEES, DEPARTMENTS zrobimy raport miesięcznych wynagrodzeń. Wyświetlimy sumę wynagrodzeń pracowników w poszczególnych działach,  policzymy ilu pracuje tam pracowników i jaka jest ich średnia pensja.

SELECT

DEPARTMENTS.DEPARTMENT_NAME,

SUM(EMPLOYEES.SALARY) AS SUMA_WYNAGRODZEŃ,

ROUND(AVG(EMPLOYEES.SALARY)) AS Średnie_wynagrodzenie,

COUNT(EMPLOYEES.SALARY) AS Liczba_pracowników

FROM EMPLOYEES, DEPARTMENTS

WHERE EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID

GROUP BY DEPARTMENTS.DEPARTMENT_NAME;

Otrzymujemy tabelę wynikową:

Tym razem chcemy dowiedzieć się jakie są średnie pensje dla poszczególnych stanowisk.

SELECT

JOBS.JOB_TITLE,

SUM(EMPLOYEES.SALARY) AS SUMA_WYNAGRODZEŃ,

ROUND(AVG(EMPLOYEES.SALARY)) AS Średnie_wynagrodzenie,

COUNT(EMPLOYEES.SALARY) AS Liczba_pracowników

FROM EMPLOYEES, JOBS

WHERE EMPLOYEES.JOB_ID = JOBS.JOB_ID

GROUP BY JOBS.JOB_TITLE;

Otrzymujemy tabelę wynikową:

 Uwaga: grupować dane klauzulą GROUP_BY można wyłącznie tymi wartościami (nazwami kolumn), które występują po klauzuli SELECT. 

Teraz postaramy się wyświetlić sumy wynagrodzeń w poszczególnych miastach. Potrzebne będą tabele DEPARTMENTS, LOCATIONS, EMPLOYEES. Aby użyć tej klauzuli trzeba połączyć te trzy kolumny wspólnymi kluczami.

SELECT

LOCATIONS.CITY,

SUM(EMPLOYEES.SALARY) AS SUMA_WYNAGRODZEŃ,

COUNT(EMPLOYEES.SALARY) AS Liczba_pracowników

FROM DEPARTMENTS, LOCATIONS, EMPLOYEES

WHERE DEPARTMENTS.LOCATION_ID = LOCATIONS.LOCATION_ID AND EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID

GROUP BY LOCATIONS.CITY;

Otrzymujemy tabelę wynikową:

Teraz sprawdźmy jaka jest suma zarobków w poszczególnych grupach pracowników tak żeby było widać id grupy i nazwę grupy.

SELECT

JOBS.JOB_ID,

JOBS.JOB_TITLE,

SUM(SALARY)

FROM EMPLOYEES,JOBS

WHERE jobs.job_id = EMPLOYEES.JOB_ID

GROUP BY JOBS.JOB_TITLE,JOBS.JOB_ID;

Otrzymujemy tabelę wynikową:

Tym razem użyjemy klauzuli GROUP BY do wyświetlenia wszystkich nazwisk w kolejności alfabetycznej, większych równych od M.

SELECT LAST_NAME

FROM EMPLOYEES

WHERE LAST_NAME > 'M'

GROUP BY LAST_NAME

Otrzymujemy tabelę wynikową:

Podobnie można wyświetlić pensje pracowników powyżej 10 000. Klauzula GROUP BY w obu tych przypadkach może operować tylko na jednej kolumnie.

SELECT

SALARY

FROM EMPLOYEES

WHERE SALARY > 10000

GROUP BY SALARY;

Składnia użycia klauzuli GROUP BY:

 Klauzula GROUP BY z funkcjami agregującymi 

Chcemy dowiedzieć się jakie są sumy wynagrodzeń dla każdego działu naszej firmy.

SELECT

DEPARTMENT_ID,

SUM(SALARY)

FROM EMPLOYEES

GROUP BY DEPARTMENT_ID;

Otrzymujemy tabelę wynikową:

Składnia użycia klauzuli GROUP BY z funkcją agregującą:

 Kolumny wymienione po klauzuli GROUP BY muszą również wystąpić po instrukcji SELECT 

 

 Użycie GROUP BY z klauzulą WHERE 

Klauzula WHERE może ograniczyć działanie formuły GROUP BY do podanego warunku.

Poniżej obliczyliśmy jak jest suma zarobków w poszczególnych działach, uwzględniając wyłącznie pensje powyżej 10 000.

SELECT

DEPARTMENT_ID,

SUM(SALARY)

FROM EMPLOYEES

WHERE SALARY > 10000

GROUP BY DEPARTMENT_ID;

Otrzymujemy tabelę wynikową, sumy tylko dla wynagrodzeń powyżej 10 000.

Teraz podsumowaliśmy wszystkie wynagrodzenia mniejsze niż 8 000. Wynik posortowaliśmy malejąco według uzyskanych sum.

SELECT

DEPARTMENT_ID,

SUM(SALARY) AS Suma_wynagrodzeń

FROM EMPLOYEES

WHERE SALARY < 8000

GROUP BY DEPARTMENT_ID

ORDER BY Suma_wynagrodzeń DESC;

 ORDER BY musi być zawsze umieszczone na końcu zapytania 

Otrzymujemy tabelę wynikową: