gpt4 book ai didi

Using rank() in Postgres(在Postgres中使用rank())

翻译 作者:bug小助手 更新时间:2023-10-26 22:18:42 27 4
gpt4 key购买 nike



I have the following tables (simplified) in Postgres:

我在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)
);

I like to know how a certain political party performs in elections. To do so I wrote a simple query:

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


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;

This gives the following result:

这将产生以下结果:


+------------+------+-----------------------------------+-----+
| 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 |
+------------+------+-----------------------------------+-----+

I'd like to add one more information: the rank of each political party in election as measured by its vote share. I can do this for a single election (see result below) but my code won't work for the above written query. Please find below my working query for single election:

我想补充一个信息:每个政党在选举中的排名,以其得票率衡量。我可以为一个单一的选举(见下面的结果),但我的代码不会为上述书面查询工作。请在下面找到我对单一选举的工作查询:


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;

and the result:

结果是:


+------+----------------------------------+-------------+------+---+
| 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 |
+------+----------------------------------+-------------+------+---+

I use Postgres 14 but I can install 15 if needed.

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


UPDATE

更新


Please have a look at the following data. It shows election result for one year only. Déi Gréng ranks fourth in this election.

请看一下以下数据。它只显示一年的选举结果。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 |
+------------+------+-----------------------------------------------+----------------------------------------------+------------+------+

No let's back to my initial query. Here I want to add rank().

不,让我们回到我最初的问题。在这里,我想添加ranch()。


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;

The query gives the following result:

该查询得到以下结果:


+------------+------+-----------------------------------+------------+------+
| 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 |
+------------+------+-----------------------------------+------------+------+

It wrongly outputs 1 for 1984 election year. It should be 4 as shown earlier. I hope I'm more clear know.

它错误地输出了1984选举年的1。如前面所示,它应该是4。我希望我能更清楚地知道。


更多回答

Can you add the expected output to your post?

你能把预期的产出加到你的帖子里吗?

The GROUP BY in your original query is redundant / unnecessary. Could you take it off and retry the rank query?

原始查询中的GROUP BY是多余的/不必要的。您可以取下它,然后重试排名查询吗?

@lemon Sure, I will do it.

@柠檬当然,我会做的。

The p.family_name condition in the WHERE clause makes your LEFT JOIN return regular INNER JOIN result. Move that condition to the ON clause to get true LEFT JOIN result. (Or switch to INNER JOIN if you want INNER JOIN result.)

WHERE子句中的p.Family_name条件使您的LEFT JOIN返回常规的INTER JOIN结果。将该条件移到ON子句以获得真正的左联接结果。(或者,如果希望获得内部联接结果,请切换到内部联接。)

But, by adding the filter you have removed the other parties like conservative and social democratic and they are no longer part of the ranking set. If you need to correct rank across parties, rank, you'll have to first write a query that gets you the rank and then nest it under another query on which you may apply the filter.

但是,通过添加过滤器,你已经删除了保守派和社会民主党等其他政党,他们不再是排名的一部分。如果您需要更正各方之间的排名,您必须首先编写一个查询来获取排名,然后将其嵌套在另一个您可以应用过滤器的查询下。

优秀答案推荐

If you want to include rank of each political part's vote share in every election year, you can modify your query like this:

如果您想要包括每个选举年每个政治部分的选票份额排名,您可以这样修改您的查询:


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;


SELECT * FROM

(SELECT
e.country_name,
extract(year FROM e.e_date) AS year,
e.party_name,
p.family_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 e.country_name = 'Luxembourg'
AND e.e_date >= '1980-01-01'::date
AND e.e_date < '2020-01-01'::date
ORDER BY
e.country_name,
year
)

WHERE family_name IN ('Green/Ecologist')

更多回答

This query gives wrong results - exactly the same as mine query.

这个查询给出了错误的结果-与我的查询完全相同。

It did the trick, thank you! I needed to add alias to sub query to make it work.

它成功了,谢谢你!我需要向子查询添加别名才能使其工作。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com