0

考虑下表:

    tbl_start_times

    id mach_id start_time
    -- ------- ----------
    1  1       00:12
    2  3       05:18
    3  1       03:56
    4  2       01:51
    5  1       12:48
    6  2       00:10
    7  3       09:15

我想为每个 mach_id 返回 id、mach_id 和 MIN(start_time)。

编码:

    SELECT mach_id, MIN(start_time) FROM tbl_start_times GROUP BY mach_id

返回此结果:

    mach_id start_time
    ------- ----------
    1       00:12
    3       05:18
    2       00:10

如何将 id 添加到我的结果中以便我得到这个?

    id mach_id start_time
    -- ------- ----------
    1  1       00:12
    2  3       05:18
    6  2       00:10
4

3 回答 3

2

在 Postgres 中有两种方法可以做到这一点:

使用 Postgres 特定的distinct on ()运算符:

SELECT distinct on (match_id) id, match_id, start_time
FROM tbl_start_times 
ORDER BY match_id, start_time;

或者使用窗口函数:

with numbered_times as (
    select id, match_id, start_time, 
           row_number() over (partition by match_id order by start_time) as rn
    from tbl_start_times 
) 
select id, match_id, start_time
from numbered_times
where rn = 1;

当您使用 distinct on(或最小/最大解决方案)时,这还可以让您轻松选择“第二”或“第四”行,而不仅仅是“第一”或“最后”

如果多行是“最低的”(即相同 match_id 具有相同的最低时间)并且您想查看所有行,请使用dense_rank()而不是row_number()

的解决方案distinct on通常比使用窗口函数的相应解决方案更快。然而,窗口函数是标准 SQL,并且在(几乎)所有现代 DBMS 上运行。这两个版本通常比使用子查询或派生表的解决方案更快,因为读取数据只需要一次。

SQLFiddle 示例:http ://sqlfiddle.com/#!12/caa95/5

于 2013-10-17T21:02:19.933 回答
1

您可以使用相关子查询执行此操作,如下所示:

SELECT id, mach_id, start_time
FROM tbl_start_times tst
WHERE start_time = (SELECT MIN(start time) 
                    FROM tbl_start_times tst2
                    WHERE tst2.mach_id = tst.mach_id)
ORDER BY id

SQL小提琴

于 2013-10-17T21:02:13.593 回答
0

尝试这个:

SELECT t.id , t.mach_id, t.start_time
FROM tbl_start_times t, 
    (SELECT mach_id, MIN(start_time) as start_time
    FROM tbl_start_times 
    GROUP BY mach_id) t1
WHERE t.mach_id=t1.mach_id AND t.start_time=t1.start_time
于 2013-10-17T21:02:07.247 回答