查询表中所有先前职位的总和,不包括当前职位

时间:2019-08-05 08:07:33

标签: postgresql

我有一个数据库表,其中:

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

2 个答案:

答案 0 :(得分: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列的逻辑。

答案 1 :(得分:0)

@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)