Voici une approche qui pourrait faire le travail. La logique consiste à utiliser des sous-requêtes agrégées pour effectuer les calculs intermédiaires.
Cette requête obtient les revenus de la On_sale
tableau par année.
SELECT
YEAR(sale_date) yr,
SUM(sale_price) amt
FROM
On_sale
GROUP BY
YEAR(sale_date);
Cette autre requête obtient le chiffre d'affaires par magasin et par an, à l'aide des tables Sold
et 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);
Nous pouvons maintenant JOIN
les résultats de ces requêtes avec la City
et Store
les tables. En même temps, nous pouvons diviser les villes en différentes catégories de taille et les utiliser pour agréger les résultats. J'utilise LEFT JOIN
dans le cas où l'une des sous-requêtes produit un jeu de résultats vide (sinon, INNER JOIN
ça va):
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
Cette démo sur DB Fiddle avec vos exemples de données illustre les étapes intermédiaires et renvoie enfin :
| sale_year | size_range | revenue |
| --------- | ---------- | ------- |
| 2017 | small | 15 |
| 2018 | medium | 14 |
| 2019 | large | 12 |