Получение ранга (номера строки) за каждый год - PullRequest
0 голосов
/ 23 февраля 2019

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

SELECT 
      cp.year as year, 
      emissions, 
      ci.id as countryid, 
      country_name, 
      country_iso_code, 
      emissions / population as per_capita, 
      CASE WHEN emissions / population IS NULL THEN NULL ELSE RANK() OVER (ORDER 
      BY CASE WHEN emissions / population IS NULL THEN 1 ELSE 0 END, emissions / 
      population DESC) END AS rank 
FROM country_emissions ce 
      RIGHT JOIN 
                 country_info ci ON (ci.countryid = ce.countryid) 
      RIGHT JOIN 
                 country_population cp ON (ce.countryid = cp.countryid) AND (cp.year = ce.year) 
WHERE 
      cp.year = 2010 
GROUP BY 
      ce.countryid, ce.year, ce.emissions, ci.id, ci.countryid, ci.country_iso_code, ci.country_name, cp.id, cp.countryid, cp.year, cp.population 
ORDER BY 
    emissions / population;

И он даст мне следующие результаты:

 year |  emissions  | countryid |          country_name          | country_iso_code |         per_capita         | rank
------+-------------+-----------+--------------------------------+------------------+----------------------------+------
 2010 |     212.686 |        14 | Burundi                        | BDI              | 0.000024260031732887110996 |  201
 2010 |    2020.517 |        40 | Congo, Dem. Rep.               | COD              | 0.000031314550846568314439 |  200
 2010 |     517.047 |       187 | Chad                           | TCD              | 0.000043496106148444352170 |  199
 2010 |     612.389 |       174 | Somalia                        | SOM              | 0.000050807074589095381376 |  198
 2010 |     590.387 |       165 | Rwanda                         | RWA              | 0.000057616483205264607379 |  197
 2010 |     264.024 |        32 | Central African Republic       | CAF              | 0.000059350908447181931090 |  196

и т. Д.

Теперь к вопросу.Есть ли способ получить rank и per_capita для каждого года и каждой страны, если мы опускаем WHERE cp.year = 2010 из запроса?

Таким образом, результат будет примерно таким:

 year |  emissions  | countryid |          country_name          | country_iso_code |         per_capita         | rank
------+-------------+-----------+--------------------------------+------------------+----------------------------+------
 2010 |     212.686 |        14 | Burundi                        | BDI              | 0.000024260031732887110996 |  201
 2009 |     210.686 |        14 | Burundi                        | BDI              | 0.000024260031732887110996 |  200
 2010 |    2020.517 |        40 | Congo, Dem. Rep.               | COD              | 0.000031314550846568314439 |  200
 2011 |    2020.517 |        40 | Congo, Dem. Rep.               | COD              | 0.000031314550846568314439 |  201

и т. Д.

Таким образом, в основном, запрашивайте все из таблиц и получайте рейтинг для каждой страны.Я понял, что partition by может быть здесь полезным, но я не знаю, где он будет соответствовать в приведенном выше запросе, поскольку замена ORDER BY на него дает забавные результаты.

Это для создания APIкоторый показывает каждые годы данные о выбросах для конкретной страны, и где они ранжируются в per_capita за указанный год.

1 Ответ

0 голосов
/ 23 февраля 2019

Во-первых, вы можете упростить rank() до:

RANK() OVER (ORDER BY COALESCE(emissions / NULLIF(population, 0), 0) DESC) as rank

Если вы хотите rank только на один год, то вы можете сделать это:

(sum(case when cp.year = 2010 then 1 else 0 end) over
 (order by case when cp.year = 2010 then coalesce(emissions / nullif(population, 0) end) -
 sum(case when cp.year = 2010 then 1 else 0 end) over (partition by cp.year, coalesce(emissions / nullif(population, 0)) +
 1
)

Ранжирование немного сложнее, потому что вы должны учитывать дубликаты с одинаковыми значениями.В противном случае вы можете просто сделать:

select . . .,
       max(case when year = 2010 then rank_year end) over (partition by countryid) as rank_2010
from (select . . .,
             rank() over (order by coalesce(emissions / nullif(population, 0), 0) desc) as rank_year

      from . . .
     ) t
...