我在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,
    sum(e.vote_share) AS vote_share
FROM
    election e
    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 = 'Austria'
    AND e.e_date >= '1980-01-01'::date
    AND e.e_date < '2020-01-01'::date
GROUP BY
    e.country_name,
    e.e_date

我想知道某个政党家族在几十年的选举中表现如何,即.1980-1989年、1990-1999年及以后各年的投票率是多少?幸运的是,Postgresdate_trunc功能,这正是我想要的.我编写了以下查询:

SELECT
    e.country_name,
    sum(e.vote_share) AS vote_share,
    extract(year FROM date_trunc('decade', e.e_date)) || 's' AS decade
    FROM
    election e
    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 = 'Austria'
    AND e.e_date >= '1980-01-01'::date
    AND e.e_date < '2020-01-01'::date
GROUP BY
    e.country_name,
    decade

它不会产生正确的结果,因为它似乎只是简单地将投票权份额相加.相反,该查询应将给定十年内每次选举的选票份额相加,然后除以该十年内的选举次数.我该怎么做?

以下是我的错误结果:

|country_name|vote_share|decade|
|------------|----------|------|
|Austria     |8.2       |1980s |
|Austria     |26.3      |1990s |
|Austria     |31        |2000s |
|Austria     |36.4      |2010s |
--------------------------------

根据 comments ,我提供了输入数据:

+---------+------+------------+
| country | year | vote_share |
+---------+------+------------+
| Austria | 1983 |        1.4 |
| Austria | 1983 |        2.0 |
| Austria | 1986 |        4.8 |
| Austria | 1990 |        4.8 |
| Austria | 1990 |        2.0 |
| Austria | 1994 |        7.3 |
| Austria | 1995 |        4.8 |
| Austria | 1999 |        7.4 |
+---------+------+------------+

预期结果:

1980s: sum: 1,4 + 2 + 4,8 = 8,2
average vote share: 8,2 / 2 = 4,1 --  here I divide by 2 because there were two elections (1983, 1986)

推荐答案

相反,该查询应将给定十年内每次选举的选票份额相加,然后除以该十年内的选举次数.

没有什么能阻止你对aggregate expressions做算术,就像你说的那样:

sum(e.vote_share) --'sum the vote share in each election in a given decade'
  /                                 --'and then divide'
count(distinct                      --'by the number'
      extract(year FROM e.e_date) ) --'of elections in that decade'

第二个函数计算不同的选举年,这些选举年本质上是在你已经分组的十年内是唯一的,有效地给出了那个十年的选举次数.Demo:

SELECT
    e.country_name,
    extract(year FROM date_trunc('decade', e.e_date)) || 's' AS decade,
    sum(e.vote_share)/count(distinct extract(year FROM e.e_date)) AS vote_share
FROM election e
    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 = 'Austria'
    AND e.e_date >= '1980-01-01'::date
    AND e.e_date < '2020-01-01'::date
GROUP BY
    e.country_name,
    decade
country_name decade vote_share
Austria 1980s 4.1000000000000000
Austria 1990s 6.5750000000000000

除了添加您想要的一个部门外,您的查询可以保持不变.

Sql相关问答推荐

带有双引号的json在Presto中是否有区别对待?

创建每小时重置的序列号

使用sede获取不一定有两个不同标签的所有问题

基于唯一值在Access查询中创建计数器

如果多行科目有一行在指定的日期范围内,如何 Select 该科目在该日期之前的所有行?

SQL数据库规范化与数据插入

在SQL中将项分配给容器

配置单元查询失败:无法识别';附近的输入;LEFT'';(select子句中的';';col'

在同一列上迭代时计算持续时间

将 jsonb 数组中的对象取消嵌套到单独的行中

使用 union 的有序结果获取行数

MySQL中的递归查询邻接表深度优先?

在where语句中使用CTE非常缓慢

Teradata 多个进程的最大进程结束时间捕获

将 MERGE 语句与 Oracle PL/SQL 表类型一起使用时,导致无效数据类型错误的原因是什么?

基于源表的 SQL INSERT、UPDATE 和 DELETE

在 MS Access 中连接相关记录

并非所有变量都绑定在 PL SQL 函数中

根据开始/结束标记将 GROUP_ID 分配给行

SQL Server Where 条件