SQL - 根据特定列上的出现从 select 中删除元组

SQL - Remove tuples from a select based on occurences on a specific column

考虑代表种族历史的简单 table:

 laphistory(race_id integer,lap_number integer,pos_number integer,
 driver_label text,id integer NOT NULL,CONSTRAINT id PRIMARY KEY (id) ...)

现在,考虑以下示例:

race_id;lap_number;pos_number;driver_label;id
1      ;1         ;1         ;"Matheus"   ;1
1      ;1         ;2         ;"Nicolas"   ;2
1      ;1         ;3         ;"Diego"     ;3
1      ;2         ;1         ;"Nicolas"   ;4
1      ;2         ;2         ;"Diego"     ;5
1      ;2         ;3         ;"Matheus"   ;6
1      ;3         ;1         ;"Nicolas"   ;7
1      ;3         ;2         ;"Diego"     ;8
1      ;4         ;1         ;"Diego"     ;9

根据上面的例子,第一场比赛的结果(对每个车手最后一圈的位置进行排序)应该是(这里可以忽略"pos_number"):

race_id;lap_number;pos_number;driver_label;id
1      ;4         ;1         ;"Diego"     ;9
1      ;3         ;1         ;"Nicolas"   ;7
1      ;2         ;3         ;"Matheus"   ;6

使用简单查询查询 BD:

select * from laphistory order by lap_number DESC, pos_number ASC

会带来如下结果:

race_id;lap_number;pos_number;driver_label;id
1      ;4         ;1         ;"Diego"     ;9  <<<
1      ;3         ;1         ;"Nicolas"   ;7  <<<
1      ;3         ;2         ;"Diego"     ;8
1      ;2         ;1         ;"Nicolas"   ;4
1      ;2         ;2         ;"Diego"     ;5
1      ;2         ;3         ;"Matheus"   ;6  <<<
1      ;1         ;1         ;"Matheus"   ;1
1      ;1         ;2         ;"Nicolas"   ;2
1      ;1         ;3         ;"Diego"     ;3

如果我们考虑每个driver.However的第一次出现是正确的,我不知道如何select。有什么想法吗?

可以应用 PostgreSQL 的 window function 以获得所需的输出:

SELECT *
FROM (
    SELECT *
        ,row_number() OVER (
            PARTITION BY driver_label ORDER BY lap_number DESC
            ) AS rank
    FROM race
    ) t
WHERE rank = 1

或者

SQL-DISTINCT

SELECT DISTINCT ON (driver_label) *
FROM race
ORDER BY driver_label ASC 
    ,lap_number DESC

简单的 GROUP BY 应该可以满足您的需要:

select race_id, lap_number, min(id) from foo
group by race_id, lap_number
order by race_id asc, lap_number desc

感谢 Vivek.S 的精彩回答,我找到了解决方案。刚刚做了一些改编:

SELECT *
FROM (
    SELECT *
        ,row_number() OVER (
            PARTITION BY driver_label ORDER BY lap_number DESC
            ) AS rank
    FROM laphistory  where lap_number<= $X$ 
    ) t
WHERE rank = 1 order by lap_number DESC, pos_number ASC

现在我可以让车手订购一圈 $x$。 谢谢!