Aquí hay un enfoque que podría hacer el trabajo. La lógica es usar subconsultas agregadas para hacer los cálculos intermedios.
Esta consulta obtiene los ingresos de On_sale
tabla por año.
SELECT
YEAR(sale_date) yr,
SUM(sale_price) amt
FROM
On_sale
GROUP BY
YEAR(sale_date);
Esta otra consulta obtiene los ingresos por tienda y por año, usando las tablas Sold
y 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);
Ahora podemos JOIN
los resultados de estas consultas con la City
y Store
mesas. Al mismo tiempo, podemos dividir las ciudades en diferentes categorías de tamaño y usar eso para agregar los resultados. Estoy usando LEFT JOIN
en caso de que una de las subconsultas produzca un conjunto de resultados vacío (de lo contrario, INNER JOIN
está bien):
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
Esta demostración en DB Fiddle con sus datos de muestra demuestra los pasos intermedios y finalmente devuelve:
| sale_year | size_range | revenue |
| --------- | ---------- | ------- |
| 2017 | small | 15 |
| 2018 | medium | 14 |
| 2019 | large | 12 |