Hier is een aanpak die de klus zou kunnen klaren. De logica is om geaggregeerde subquery's te gebruiken om de tussentijdse berekeningen uit te voeren.
Deze zoekopdracht krijgt de opbrengst van de On_sale
tabel per jaar.
SELECT
YEAR(sale_date) yr,
SUM(sale_price) amt
FROM
On_sale
GROUP BY
YEAR(sale_date);
Deze andere zoekopdracht krijgt de opbrengst per winkel en per jaar, met behulp van tabellen Sold
en Product
:
SELECT
s.store_number,
YEAR(s.sold_date) yr,
SUM(s.sold_quantity * p.retail_price) amt
FROM
Sold s
INNER JOIN Product p
ON p.pid = s.pid
GROUP BY
s.store_number,
YEAR(sold_date);
Nu kunnen we JOIN
de resultaten van deze zoekopdrachten met de City
en Store
tafels. Tegelijkertijd kunnen we de steden opsplitsen in verschillende groottecategorieën en die gebruiken om de resultaten te aggregeren. Ik gebruik LEFT JOIN
in het geval dat een van de subquery's een lege resultatenset oplevert (anders, INNER JOIN
is in orde):
SELECT
COALESCE(sa.yr, so.yr) sale_year,
CASE
WHEN c.population > 200 THEN 'large'
WHEN c.population <= 200 AND c.population > 100 THEN 'medium'
ELSE 'small'
END as size_range,
SUM(COALESCE(so.amt, 0) + COALESCE(sa.amt, 0)) revenue
FROM
City c
INNER JOIN Store st
ON st.state = c.state
AND st.city_name = c.city_name
LEFT JOIN (
SELECT
s.store_number,
YEAR(s.sold_date) yr,
SUM(s.sold_quantity * p.retail_price) amt
FROM
Sold s
INNER JOIN Product p
ON p.pid = s.pid
GROUP BY
s.store_number,
YEAR(sold_date)
) so
ON so.store_number = st.store_number
LEFT JOIN (
SELECT
YEAR(sale_date) yr,
SUM(sale_price) amt
FROM
On_sale
GROUP BY
YEAR(sale_date)
) sa
ON sa.yr = so.yr
GROUP BY
sale_year,
size_range
ORDER BY
sale_year,
size_range
Deze demo op DB Fiddle met uw voorbeeldgegevens demonstreert u de tussenstappen en geeft u uiteindelijk het volgende terug:
| sale_year | size_range | revenue |
| --------- | ---------- | ------- |
| 2017 | small | 15 |
| 2018 | medium | 14 |
| 2019 | large | 12 |