Как с помощью SQLite рассчитать максимальный годовой темп роста для каждого года? - PullRequest
1 голос
/ 13 июля 2020

Я изучаю SQL и выполняю практическое упражнение под названием World Populations SQL Practice on Codecademy. Есть одна таблица с тремя столбцами: страна, население и год. Мне интересно рассчитывать страну с максимальным годовым темпом роста каждый год. (Это не было предложено Codecademy, я просто думаю, что это интересная идея).

Я могу рассчитать все темпы роста в годовом исчислении с помощью этого запроса:

SELECT country,
       100.0 * ((SELECT population FROM population_years AS p2
                 WHERE p2.year = p1.year + 1
                 AND p2.country = p1.country)
                 - population) / population AS year_on_year_growth,
       year
FROM population_years AS p1
WHERE year_on_year_growth IS NOT NULL
ORDER BY year_on_year_growth;

и я могу рассчитать максимальные темпы роста в годовом исчислении для конкретного года, например 2005, с помощью такого запроса:

SELECT country,
       100.0 * ((SELECT population FROM population_years AS p2
                 WHERE p2.year = p1.year + 1
                 AND p2.country = p1.country)
                 - population) / population AS year_on_year_growth,
       year
FROM population_years AS p1
WHERE year = 2005
AND year_on_year_growth IS NOT NULL
ORDER BY year_on_year_growth DESC
LIMIT 1;

Используя python, я могу решить проблему с помощью первый запрос, сохраненный как yoy_query, если я сделаю это:

yoy_result = c.execute(yoy_query).fetchall()
sorted([record for record in yoy_result if record[1] == max([row[1] for row in yoy_result if row[2] == record[2]])],key=lambda x:x[2])

, и я получу желаемый результат:

[('Montserrat', 7.34177215189872, 2000), ('Montserrat', 13.4433962264151, 2001), ('Afghanistan', 5.803891762260126, 2002), ('Montserrat', 10.467706013363028, 2003), ('Liberia', 4.7976709085316545, 2004), ('Jordan', 7.088496587486171, 2005), ('Jordan', 6.764378108744186, 2006), ('Montserrat', 12.638580931263864, 2007), ('Liberia', 4.157111008408977, 2008), ('Niger', 3.737166190281749, 2009)]

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

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Вы можете сделать это с помощью оконных функций LAG() и RANK():

select country, year_on_year_growth, year
from (
  select *, rank() over (partition by year order by year_on_year_growth desc) as rnk
  from (
    select *, 
      100.0 * (population / lag(population) over (partition by country order by year) - 1) as year_on_year_growth
    from population_years 
  )
)

Выражение:

lag(population) over (partition by country order by year)

возвращает население страны предыдущий год (при условии отсутствия разрывов между годами). Итак, я рассчитал скорость роста как:

((население текущего года) / (население предыдущего года)) - 1

0 голосов
/ 13 июля 2020

Думаю, проще всего было бы просто использовать представление следующим образом:

CREATE VIEW yoy_growth
AS
SELECT country,
       100.0 * ((SELECT population FROM population_years AS p2
                 WHERE p2.year = p1.year + 1
                 AND p2.country = p1.country)
                 - population) / population AS year_on_year_growth,
       year
FROM population_years AS p1
WHERE year_on_year_growth IS NOT NULL
ORDER BY year_on_year_growth;

SELECT * FROM yoy_growth AS y1
WHERE year_on_year_growth = (
    SELECT MAX(year_on_year_growth)
    FROM yoy_growth AS y2
    WHERE y1.year = y2.year
)
ORDER BY year;

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

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