Рассмотрим следующий базовый запрос, который дает вам сумму каждой категории дел на city_id
. Мы можем получить эту информацию, посмотрев только на covid19cities
:
select
cvc.city_id,
sum(cvc.n_cases) sum_n_cases,
sum(cvc.r_cases) sum_r_cases,
sum(cvc.d_cases) sum_d_cases
from covid19cities cvc
group by cvc.city_id
Теперь давайте приведем таблицу cities
. Это дает те же результаты, и вы также можете отобразить название города:
select
c.id city_id,
c.name city_name,
sum(cvc.n_cases) sum_n_cases,
sum(cvc.r_cases) sum_r_cases,
sum(cvc.d_cases) sum_d_cases
from covid19cities cvc
inner join cities c on c.id = cvc.city_id
group by c.id, c.name
Исходя из этого, мы можем следовать иерархии вверх, уровень за уровнем, добавляя дополнительные объединения в таблицу cities
и изменение столбцов в предложениях select
и group by
.
Получим количество дел на родительский город : мы присоединяемся к таблице cities
во второй раз с псевдонимом pc
(для родительского города):
select
pc.id parent_city_id,
pc.name parent_city_name,
sum(cvc.n_cases) sum_n_cases,
sum(cvc.r_cases) sum_r_cases,
sum(cvc.d_cases) sum_d_cases
from covid19cities cvc
inner join cities c on c.id = cvc.city_id
inner join cities pc on pc.id = c.parent_id
group by pc.id, pc.name
Следующий уровень - это район :
select
d.id distict_id,
d.name district_name,
sum(cvc.n_cases) sum_n_cases,
sum(cvc.r_cases) sum_r_cases,
sum(cvc.d_cases) sum_d_cases
from covid19cities cvc
inner join cities c on c.id = cvc.city_id
inner join cities pc on pc.id = c.parent_id
inner join cities d on d.id = pc.parent_id
group by d.id, d.name
Наконец, вот запрос, который предоставляет информацию на верхнем уровне, то есть регионе:
select
r.id region_id,
r.name region_name,
sum(cvc.n_cases) sum_n_cases,
sum(cvc.r_cases) sum_r_cases,
sum(cvc.d_cases) sum_d_cases
from covid19cities cvc
inner join cities c on c.id = cvc.city_id
inner join cities pc on pc.id = c.parent_id
inner join cities d on d.id = pc.parent_id
inner join cities r on r.id = d.parent_id
group by r.id, r.name
В качестве более общей мысли: обратите внимание, что сложность здесь заключается в том, что вы храните иерархическую структуру в таблице cities
. Было бы намного проще иметь отдельные таблицы для хранения каждой сущности с внешними ключами для представления отношений, например:
regions: region_id, region_name
districts: district_id, district_name, region_id
parent_cities: parent_city_id, parent_city_name, district_id
cities: city_id, city_name, parent_city_id
При таком дизайне ваш последний запрос будет выглядеть так:
select
r.region_id,
r.region_name,
sum(cvc.n_cases) sum_n_cases,
sum(cvc.r_cases) sum_r_cases,
sum(cvc.d_cases) sum_d_cases
from covid19cities cvc
inner join cities c on c.id = cvc.city_id
inner join parent_cities pc on pc.parent_city_id = c.parent_city_id
inner join districts d on d.district_id = pc.district_id
inner join regions r on r.region_id = d.region_id
group by r.region_id, r.region_name
Это такое же количество объединений, но вещи хранятся в разных таблицах, поэтому запрос гораздо проще писать и читать.