Подзапрос дает разные результаты при использовании отдельно - PullRequest
0 голосов
/ 28 октября 2018

Мне нужно написать запрос для двух разных таблиц country и city.Цель состоит в том, чтобы собрать каждый район и население этого района для каждой страны.Поскольку район является просто атрибутом каждого города, я должен указать все группы населения каждого города, принадлежащего округу.

Пока мой запрос выглядит следующим образом:

SELECT country.name, country.population, array_agg(
    (SELECT (c.district, sum(city.population))
     FROM city GROUP BY c.district))
    AS districts
FROM country
FULL OUTER JOIN city c ON country.code = c.countrycode
GROUP BY country.name, country.population;

результат:

                    name                     | population |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              districts                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
---------------------------------------------+------------+------------------------------------------------------------------------------------------------------------------
Afghanistan                                  |   22720000 | {"(Balkh,1429559884)","(Qandahar,1429559884)","(Herat,1429559884)","(Kabol,1429559884)"}
Albania                                      |    3401200 | {"(Tirana,1429559884)"}
Algeria                                      |   31471000 | {"(Blida,1429559884)","(Béjaïa,1429559884)","(Annaba,1429559884)","(Batna,1429559884)","(Mostaganem,1429559884)"
American Samoa                               |      68000 | {"(Tutuila,1429559884)","(Tutuila,1429559884)"}

Так что, очевидно, он суммирует все городское население мира.Мне нужно как-то ограничить это только для каждого района.

Но если я запускаю подзапрос один, как

SELECT (city.district, sum(city.population)) FROM city GROUP BY city.district;

, то это дает мне районы с их населением:

               row                
----------------------------------
(Bali,435000)
(,4207443)
(Dnjestria,194300)
(Mérida,224887)
(Kochi,324710)
(Qazvin,291117)
(Izmir,2130359)
(Meta,273140)
(Saint-Denis,131480)
(Manitoba,618477)
(Changhwa,354117)

Я понял, что это связано с аббревиатурой, которую я использую при присоединении.Я использовал его для удобства, но, похоже, он имеет реальные последствия, потому что, если я его не использую, он выдаст мне ошибку

more than one row returned by a subquery used as an expression

Кроме того, если я использую

sum(c.population)

вподзапрос не будет выполнен, потому что

aggregate function calls cannot be nested

Эта аббревиатура при присоединении явно меняет очень .

Я надеюсь, что кто-то может пролить свет на это.

1 Ответ

0 голосов
/ 28 октября 2018

Решил сам.

Оконные функции - наиболее удобный метод для такого рода задач:

SELECT DISTINCT
    country.name
    , country.population
    , city.district
    , sum(city.population) OVER (PARTITION BY city.district)
        AS district_population
    , sum(city.population) OVER (PARTITION BY city.district)/ CAST(country.population as float)
        AS district_share

FROM
    country JOIN city ON country.code = city.countrycode
;

Но он также работает с подвыборками:

SELECT DISTINCT
    country.name
    , country.population
    , city.district
    ,(
        SELECT
            sum(ci.population)
        FROM
            city ci 
            WHERE ci.district = city.district
    ) AS district_population
    ,(
        SELECT
            sum(ci2.population)/ CAST(country.population as float)
        FROM
            city ci2
            WHERE ci2.district = city.district
    ) AS district_share

FROM
    country JOIN city ON country.code = city.countrycode

ORDER BY
    country.name
    , country.population
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...