在Postgres中使用rank()

问题描述 投票:0回答:1

我在 Postgres 中有以下表格(简化):

CREATE TABLE party(
    id int PRIMARY KEY,
    family_name varchar(50) NOT NULL
);

CREATE TABLE election(
    id int,
    country_name varchar(50) NOT NULL,
    e_type election_type NOT NULL,
    e_date date NOT NULL,
    vote_share numeric,
    seats int,
    seats_total int NOT NULL,
    party_name_short varchar(10) NOT NULL,
    party_name varchar(255) NOT NULL,
    party_name_english varchar(255) NOT NULL,
    party_id int REFERENCES party(id)
);

我想知道某个政党在选举中的表现如何。为此,我编写了一个简单的查询:

SELECT
    e.country_name,
    extract(year FROM e.e_date) AS year,
    e.party_name,
    round(e.vote_share, 1) AS vote_share
FROM
    election e
    LEFT JOIN party p ON e.party_id = p.id
WHERE
    e.e_type = 'parliament'
    AND p.family_name IN ('Green/Ecologist')
    AND e.country_name = 'Luxembourg'
    AND e.e_date >= '1980-01-01'::date
    AND e.e_date < '2020-01-01'::date
GROUP BY
    e.country_name,
    e.e_date,
    e.party_name,
    e.vote_share
ORDER BY
    e.country_name,
    year;

这给出了以下结果:

+------------+------+-----------------------------------+-----+
| Luxembourg | 1984 | Déi Gréng                         | 5.2 |
| Luxembourg | 1989 | Déi Gréng                         | 4.2 |
| Luxembourg | 1989 | Greng Lëscht Ekologesch Initiativ | 4.2 |
+------------+------+-----------------------------------+-----+

我想补充一个信息:每个政党在选举中的排名,以其得票率来衡量。我可以在一次选举中执行此操作(请参阅下面的结果),但我的代码不适用于上述书面查询。请在下面找到我对单一选举的工作查询:

SELECT
    extract(year FROM e.e_date) AS year,
    e.party_name,
    e.country_name,
    round(e.vote_share, 1) AS vote_share,
    RANK() OVER (PARTITION BY e.id ORDER BY e.vote_share DESC) vote_rank_number
FROM
    election e
WHERE
    e.id = 1;

结果:

+------+----------------------------------+-------------+------+---+
| 1972 | Labour Party                     | New Zealand | 48.4 | 1 |
| 1972 | National Party                   | New Zealand | 41.5 | 2 |
| 1972 | Social Credit | Democratic Party | New Zealand |  6.7 | 3 |
| 1972 | Values Party                     | New Zealand |  2.0 | 4 |
+------+----------------------------------+-------------+------+---+

我使用 Postgres 14,但如果需要,我可以安装 15。

更新

请查看以下数据。它仅显示一年的选举结果。

Déi Gréng
在这次选举中排名第四。

+------------+------+-----------------------------------------------+----------------------------------------------+------------+------+
|  country   | year |                  party name                   |             party name original              | vote_share | rank |
+------------+------+-----------------------------------------------+----------------------------------------------+------------+------+
| Luxembourg | 1984 | Chrëschtlech Sozial Vollekspartei             | Christian Social People's Party              |       34.9 |    1 |
| Luxembourg | 1984 | Lëtzebuerger Sozialistesch Aarbechterpartei   | Luxembourg Socialist Workers' Party          |       33.6 |    2 |
| Luxembourg | 1984 | Demokratesch Partei                           | Democratic Party                             |       18.7 |    3 |
| Luxembourg | 1984 | Déi Gréng                                     | The Greens                                   |        5.2 |    4 |
| Luxembourg | 1984 | Kommunistesch Partei Lëtzebuerg               | Communist Party of Luxembourg                |        5.0 |    5 |
| Luxembourg | 1984 | Jean Gremling List – Socialistes Indépendants | Jean Gremling List -- Independent Socialists |        2.5 |    6 |
+------------+------+-----------------------------------------------+----------------------------------------------+------------+------+

不,让我们回到我最初的询问。这里我想添加rank()。

SELECT
    e.country_name,
    extract(year FROM e.e_date) AS year,
    e.party_name,
    round(e.vote_share, 1) AS vote_share,
    RANK() OVER (PARTITION BY e.id ORDER BY e.vote_share DESC) vote_rank_number
FROM
    election e
    LEFT JOIN party p ON e.party_id = p.id
WHERE
    e.e_type = 'parliament'
    AND p.family_name IN ('Green/Ecologist')
    AND e.country_name = 'Luxembourg'
    AND e.e_date >= '1980-01-01'::date
    AND e.e_date < '2020-01-01'::date
GROUP BY
    e.id,
    e.country_name,
    e.e_date,
    e.party_name,
    e.vote_share
ORDER BY
    e.country_name,
    year;

查询给出以下结果:

+------------+------+-----------------------------------+------------+------+
|  country   | year |            party name             | vote_share | rank |
+------------+------+-----------------------------------+------------+------+
| Luxembourg | 1984 | Déi Gréng                         |        5.2 |    1 |
| Luxembourg | 1989 | Greng Lëscht Ekologesch Initiativ |        4.2 |    1 |
| Luxembourg | 1989 | Déi Gréng                         |        4.2 |    2 |
| Luxembourg | 1994 | Déi Gréng                         |       10.2 |    1 |
| Luxembourg | 1999 | Greng Lëscht Ekologesch Initiativ |        1.1 |    2 |
| Luxembourg | 1999 | Déi Gréng                         |        9.1 |    1 |
| Luxembourg | 2004 | Déi Gréng                         |       11.5 |    1 |
| Luxembourg | 2009 | Déi Gréng                         |       11.7 |    1 |
| Luxembourg | 2013 | Déi Gréng                         |       10.1 |    1 |
| Luxembourg | 2018 | Déi Gréng                         |       14.1 |    1 |
+------------+------+-----------------------------------+------------+------+

它错误地为

1
选举年输出
1984
。它应该是
4
,如之前所示。我希望我更清楚地知道。

sql postgresql window-functions
1个回答
0
投票

如果您想包含每个选举年每个政治派别的投票份额排名,您可以像这样修改查询:

SELECT
    e.country_name,
    extract(year FROM e.e_date) AS year,
    e.party_name,
    round(e.vote_share, 1) AS vote_share,
    RANK() OVER (PARTITION BY extract(year FROM e.e_date) ORDER BY e.vote_share DESC) AS vote_rank_number
FROM
    election e
    LEFT JOIN party p ON e.party_id = p.id
WHERE
    e.e_type = 'parliament'
    AND p.family_name IN ('Green/Ecologist')
    AND e.country_name = 'Luxembourg'
    AND e.e_date >= '1980-01-01'::date
    AND e.e_date < '2020-01-01'::date
GROUP BY
    e.country_name,
    extract(year FROM e.e_date),
    e.party_name,
    e.vote_share
ORDER BY
    e.country_name,
    year;
© www.soinside.com 2019 - 2024. All rights reserved.