Вывести данные с чередованием в Postgresql
Всем привет! У меня есть такой код:
CREATE TABLE COUNTRY (
Id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE CITY (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
population INTEGER NOT NULL,
contryID INTEGER NOT NULL
);
INSERT INTO COUNTRY VALUES (0001, 'Russia');
INSERT INTO COUNTRY VALUES (0002, 'USA');
INSERT INTO COUNTRY VALUES (0003, 'Italy');
INSERT INTO CITY VALUES (0001, 'Moskov', 10, 0001);
INSERT INTO CITY VALUES (0002, 'Piter', 5, 0001);
INSERT INTO CITY VALUES (0003, 'Rostov', 1, 0001);
INSERT INTO CITY VALUES (0004, 'New York', 8, 0002);
INSERT INTO CITY VALUES (0005, 'Los Angeles', 4, 0002);
INSERT INTO CITY VALUES (0006, 'Las Vegas', 3, 0002);
INSERT INTO CITY VALUES (0007, 'Rome', 7, 0003);
INSERT INTO CITY VALUES (0008, 'Florentia', 5, 0003);
INSERT INTO CITY VALUES (0009, 'Vinecia', 3, 0003);
SELECT name, NULL as population FROM COUNTRY
UNION ALL
SELECT name, population FROM CITY
Если запустить этот код то получаю следующее:
| name | population |
|---|---|
| Russia | |
| USA | |
| Italy | |
| Moskov | 10 |
| Piter | 5 |
| Rostov | 1 |
| New York | 8 |
| Los Angeles | 4 |
| Las Vegas | 3 |
| Rome | 7 |
| Florentia | 5 |
| Vinecia | 3 |
А как сделать, чтоб было как указано в таблице ниже(при этом суммируя население для страны в виде итоговой строки после группы городов каждой страны и в самом конце итог по всем странам)?:
| name | population |
|---|---|
| Russia | |
| Moskov | 10 |
| Piter | 5 |
| Rostov | 1 |
| ИТОГ:Russia | 16 |
| USA | |
| New York | 8 |
| Los Angeles | 4 |
| Las Vegas | 3 |
| ИТОГ:USA | 15 |
| Italy | |
| Rome | 7 |
| Florentia | 5 |
| Vinecia | 3 |
| ИТОГ:Italy | 15 |
| ИТОГ:World | 46 |
Подойдет любой способ(Производительность имеет значение)
Ответы (3 шт):
Кажется вам нужно что-то вроде этого:
select
country.name,
city.name,
sum(population)
from
country,
city
where
country.id = city.countryid
group by
grouping sets (
(country.name),
(city.name),
()
)
order by
city.name nulls last,
country.name nulls last;
Результат же экспортируете в эксель (или обрабатываете в любом знакомом вам языке программирования) и дооформляете до нужного вам вида: писать слово "ИТОГ" и смешивать колонки названия страны и города - это не задача для PostgreSQL в общем случае.
Я сделал так
WITH selector as (
SELECT name, id, id as main,null as inside, NULL AS population
FROM COUNTRY
UNION ALL
SELECT name, contryID, null, contryID, population
FROM CITY
UNION ALL
SELECT 'ИТОГ:' || country.name, country.id,null, NULL,
SUM(city.population)
FROM COUNTRY country
JOIN CITY city ON country.id = city.contryID
GROUP BY country.name, country.id
UNION ALL
SELECT 'ИТОГ:World', null,null, NULL, SUM(population)
FROM CITY
ORDER BY id, main, inside)
SELECT name, population from selector
Если кто знает как это можно улучшить, сообщите плз
select case when ci_name is null and co_name is not null then 'Итого: '||co_name when ci_name is null and co_name is null then 'Итого: World' else co_name end
,ci_name
,s_pop
from (select COUNTRY.name as co_name,CITY.name as ci_name,sum(CITY.population) as s_pop
from COUNTRY join CITY on (COUNTRY.id=CITY.contryid) group by
rollup(COUNTRY.name,CITY.name)
order by COUNTRY.name,CITY.name) as f;
| co_name | ci_name | s_pop |
|---|---|---|
| Italy | Florentia | 5 |
| Italy | Rome | 7 |
| Italy | Vinecia | 3 |
| Итого: Italy | 15 | |
| Russia | Moskov | 10 |
| Russia | Piter | 5 |
| Russia | Rostov | 1 |
| Итого: Russia | 16 | |
| USA | Las Vegas | 3 |
| USA | Los Angeles | 4 |
| USA | New York | 8 |
| Итого: USA | 15 | |
| Итого: World | 46 |
(13 rows)