Группировать по и присоединиться - PullRequest
2 голосов
/ 21 апреля 2020

У меня проблема с использованием group by и присоединением к одному и тому же запросу. (Я использую мировую БД в MySQL, только две таблицы. Первая - страны, вторая - города). Я хочу получить самый большой город на каждом континенте. Вот что я попробовал

SELECT
    k.Continent,
    m.name,
    MAX(m.Population)
FROM
    city m
        JOIN
    country k ON m.CountryCode = k.Code
GROUP BY 1;

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

Ответы [ 2 ]

2 голосов
/ 21 апреля 2020

Вероятно, лучший способ ответить на вопрос - использовать оконные функции, row_number():

SELECT Continent, name, Population
FROM (SELECT co.Continent, ci.name, ci.Population,
             ROW_NUMBER() OVER (PARTITION BY co.Continent ORDER BY ci.Population DESC) as seqnum
      FROM city ci JOIn
           country co
           ON ci.CountryCode = co.Code
     ) cc
WHERE seqnum = 1
2 голосов
/ 21 апреля 2020

Это самая большая проблема для каждой группы. Вы хотите фильтровать скорее агрегат.

Вы можете использовать коррелированный подзапрос для этого:

select co.continent, ci.name, ci.population
from city ci
inner join country co where co.code = ci.countryCode
where ci.population = (
    select max(ci1.population)
    from city ci1
    inner join country co1 on co1.code = ci1.countryCode
    where co1.continent = co.continent
)

Если вам повезло работать с MySQL 8.0, его проще использовать оконные функции:

select *
from (
    select 
        co.continent, 
        ci.name, 
        ci.population, 
        rank() over(partition by co.continent order by ci.population desc) rn
    from city ci
    inner join country co where co.code = ci.countryCode
) t
where rn = 1
...