【问题标题】:Query table with sum of ALL previous positions, excluding current position查询包含所有先前位置总和的表,不包括当前位置
【发布时间】:2019-08-05 08:07:33
【问题描述】:

我有一个数据库表:

id | date       | position | name
--------------------------------------
1  | 2016-06-29 | 9        | Ben Smith
2  | 2016-06-29 | 1        | Ben Smith
3  | 2016-06-29 | 5        | Ben Smith
4  | 2016-06-29 | 6        | Ben Smith
5  | 2016-06-30 | 2        | Ben Smith
6  | 2016-06-30 | 2        | Tom Brown
7  | 2016-06-29 | 4        | Tom Brown
8  | 2016-06-30 | 2        | Tom Brown
9  | 2016-06-30 | 1        | Tom Brown

如何有效地查询表,以便使用 sum() 获取新列。

我希望表格输出看起来像这样


id | date       | position | name      | races | wins | places
--------------------------------------------------------------
1  | 2016-06-29 | 9        | Ben Smith | 1     | 0    | 0
2  | 2016-06-29 | 1        | Ben Smith | 2     | 1    | 0
3  | 2016-06-29 | 5        | Ben Smith | 3     | 1    | 0
4  | 2016-06-29 | 6        | Ben Smith | 4     | 1    | 0
5  | 2016-06-30 | 2        | Ben Smith | 5     | 1    | 1
6  | 2016-06-30 | 2        | Tom Brown | 1     | 0    | 2
7  | 2016-06-29 | 4        | Tom Brown | 1     | 0    | 2
8  | 2016-06-30 | 2        | Tom Brown | 2     | 0    | 3
9  | 2016-06-30 | 1        | Tom Brown | 4     | 1    | 3

【问题讨论】:

  • 你应该清楚地解释每列是如何到达的,而不是期望读者花时间去理解它。另外,请向我们展示您尝试过的查询。
  • @KaushikNayak 抱歉没有发布代码,我不知道如何开始。我从下面的答案中提取并对其进行了扩展。

标签: postgresql


【解决方案1】:

看起来这可以使用窗口函数轻松完成:

select id, date, position, name, 
       row_number(*) over (partition by name, date order by id) as races,
       count(*) filter (where position = 1) over (partition by name, date)  as wins
from the_table;

我不明白计算places 列的逻辑。

【讨论】:

  • 我认为地点:位置 = 2
  • @FatFreddy:我也这么认为,但这对 Tom Brown 不起作用(只有两个位置 = 2 并且在不同的日子)
【解决方案2】:

@FatFreddy @a_horse_with_no_name

感谢您让我开始,这就是我想出的。你认为它可以改进吗?

WITH runners AS (
    SELECT 
        r.*,
        CASE
            WHEN position = 1 THEN 1
            ELSE 0
        END AS win,
        CASE
            WHEN position = 2 THEN 1
            WHEN position = 3 THEN 1
            ELSE 0
        END AS place
    FROM 
        runners r
    ORDER BY id
)   
SELECT 
    date, 
    r.id, 
    r.position, 
    name,
    row_number(*) OVER foo AS races,
    sum(win) OVER foo AS win,
    sum(place) OVER foo AS place
FROM 
    runners r
LEFT JOIN markets m ON m.id = r.market_id
WINDOW foo AS (PARTITION BY name) ORDER BY r.id)

【讨论】:

    猜你喜欢
    • 2019-08-27
    • 2019-09-24
    • 1970-01-01
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多