Посмотрим на решение задания про сотрудников, которые продали меньше, чем среднестатистический сотрудник.
В запросе
WITH employee_result AS (
SELECT p.employee_id,
sum (pi.price * pi.count) AS sum_purchases
FROM purchase p,
purchase_item pi
WHERE pi.purchase_id = p.purchase_id
AND p.employee_id IS NOT NULL
GROUP BY p.employee_id
)
SELECT er.employee_id,
e.last_name,
e.first_name,
er.sum_purchases
FROM employee_result er,
employee e
WHERE e.employee_id = er.employee_id
AND er.sum_purchases < (SELECT avg (ern.sum_purchases)
FROM employee_result ern)
ORDER BY er.sum_purchases,
er.employee_id
мы ссылаемся на таблицу employee_result
дважды: во фразе FROM
и в подзапросе
(SELECT avg (ern.sum_purchases)
FROM employee_result ern)
Это очень удобно. Один раз написал и используешь сколько нужно.
Несколько подзапросов
Пойдем дальше в анализе продаж сотрудниками. Добавим в результат сумму продаж по каждому магазину.
WITH employee_result AS (
SELECT p.employee_id,
p.store_id,
sum (pi.price * pi.count) AS sum_purchases
FROM purchase p,
purchase_item pi
WHERE pi.purchase_id = p.purchase_id
AND p.employee_id IS NOT NULL
GROUP BY p.employee_id,
p.store_id
),
store_result AS (
SELECT er.store_id,
sum (er.sum_purchases) AS sum_purchases
FROM employee_result er
GROUP BY er.store_id
)
SELECT s.name AS store_name,
e.last_name,
e.first_name,
er.sum_purchases AS sum_purchases_employee,
sr.sum_purchases AS sum_purchases_store
FROM employee_result er,
store_result sr,
employee e,
store s
WHERE sr.store_id = er.store_id
AND e.employee_id = er.employee_id
AND s.store_id = er.store_id
ORDER BY s.name,
er.sum_purchases
# | store_name | last_name | first_name | sum_purchases_employee | sum_purchases_store |
---|---|---|---|---|---|
1 | Big | Громов | Юлиан | 1321800000.00 | 1321800000.00 |
2 | Umi | Агафьев | Мирон | 158800.00 | 411300.00 |
3 | Umi | Белозёров | Зиновий | 252500.00 | 411300.00 |
4 | Адалин-family | Суханов | Влас | 4900.00 | 4900.00 |
5 | Март | Картман | Эрик | 47000.00 | 847800.00 |
6 | Март | Миронова | Зарина | 800800.00 | 847800.00 |
7 | Пионер | Блинова | Любовь | 52200.00 | 52200.00 |
8 | Сатурн | Корсаков | Петр | 121500.00 | 121500.00 |
После подзапроса employee_result
в WITH
появился еще один подзапрос
store_result AS (
SELECT er.store_id,
sum (er.sum_purchases) AS sum_purchases
FROM employee_result er
GROUP BY er.store_id
)
Стоит отметить, что в WITH
:
- Можно писать несколько подзапросов.
- Использовать выше определенные подзапросы вместо таблиц.
В основном запросе
SELECT s.name AS store_name,
e.last_name,
e.first_name,
er.sum_purchases AS sum_purchases_employee,
sr.sum_purchases AS sum_purchases_store
FROM employee_result er,
store_result sr,
employee e,
store s
WHERE sr.store_id = er.store_id
AND e.employee_id = er.employee_id
AND s.store_id = er.store_id
ORDER BY s.name,
er.sum_purchases
Используется и employee_result
, и store_result
.
Разработка запроса
С использованием WITH
очень удобно разрабатывать запрос с несколькими подзапросами.
Например, в запросе
WITH employee_result AS (
SELECT p.employee_id,
p.store_id,
sum (pi.price * pi.count) AS sum_purchases
FROM purchase p,
purchase_item pi
WHERE pi.purchase_id = p.purchase_id
AND p.employee_id IS NOT NULL
GROUP BY p.employee_id,
p.store_id
),
store_result AS (
SELECT er.store_id,
sum (er.sum_purchases) AS sum_purchases
FROM employee_result er
GROUP BY er.store_id
)
SELECT s.name AS store_name,
e.last_name,
e.first_name,
er.sum_purchases AS sum_purchases_employee,
sr.sum_purchases AS sum_purchases_store
FROM employee_result er,
store_result sr,
employee e,
store s
WHERE sr.store_id = er.store_id
AND e.employee_id = er.employee_id
AND s.store_id = er.store_id
ORDER BY s.name,
er.sum_purchases
посмотрим, что возвращает каждый подзапрос. Для этого комментируем (или удаляем, мы для краткости удалим) основной запрос и оставляем SELECT *
из интересующего подзапроса.
Посморим, что в employee_result
:
WITH employee_result AS (
SELECT p.employee_id,
p.store_id,
sum (pi.price * pi.count) AS sum_purchases
FROM purchase p,
purchase_item pi
WHERE pi.purchase_id = p.purchase_id
AND p.employee_id IS NOT NULL
GROUP BY p.employee_id,
p.store_id
),
store_result AS (
SELECT er.store_id,
sum (er.sum_purchases) AS sum_purchases
FROM employee_result er
GROUP BY er.store_id
)
SELECT *
FROM employee_result
# | employee_id | store_id | sum_purchases |
---|---|---|---|
1 | 25 | 100 | 52200.00 |
2 | 8 | 201 | 121500.00 |
3 | 43 | 301 | 4900.00 |
4 | 29 | 500 | 800800.00 |
5 | 15 | 500 | 47000.00 |
... | ... | ... | ... |
Что в store_result
:
WITH employee_result AS (
SELECT p.employee_id,
p.store_id,
sum (pi.price * pi.count) AS sum_purchases
FROM purchase p,
purchase_item pi
WHERE pi.purchase_id = p.purchase_id
AND p.employee_id IS NOT NULL
GROUP BY p.employee_id,
p.store_id
),
store_result AS (
SELECT er.store_id,
sum (er.sum_purchases) AS sum_purchases
FROM employee_result er
GROUP BY er.store_id
)
SELECT *
FROM store_result
# | store_id | sum_purchases |
---|---|---|
1 | 100 | 52200.00 |
2 | 201 | 121500.00 |
3 | 301 | 4900.00 |
4 | 500 | 847800.00 |
... | ... | ... |