5

我有一个具有以下结构的表:

id          timestamp       area
717416915   18:30:53.063    25.691601
717416915   18:31:34.863    31.200506
717416915   18:32:23.665    25.690088
1994018321  18:32:45.467    37.409171
1994018321  18:33:19.612    37.409171
424164505   18:36:16.634    18.22091
424164505   18:36:36.899    18.210754
424164505   18:37:08.614    19.829266
2394018356  18:37:27.231    79.31705

我想要做的是以这样一种方式总结这些值,以便我可以识别每个 的区域id,按 排序timestamp。例如,如果我想要第一个area值,它将如下:

id          timestamp       area_1
717416915   18:30:53.063    25.691601
1994018321  18:32:45.467    37.409171
424164505   18:36:16.634    18.22091
2394018356  18:37:27.231    79.31705

如果我想获得第二个area值,id它将如下:

id          timestamp       area_2
717416915   18:31:34.863    31.200506
1994018321  18:33:19.612    37.409171
424164505   18:36:36.899    18.210754

我知道我需要按时间排序,然后确定每个id. 我不太明白如何做到这一点。我尝试做的是以下(没有运行,因为我仍然不清楚如何使用该OVER功能)。

WITH T AS (
    SELECT * OVER(PARTITION BY a.id ORDER BY a.timestamp) AS rnk
    FROM mytable AS a
) 
SELECT area as area_1
FROM T
WHERE rnk = 1
GROUP BY a.id
ORDER BY a.timestamp;

我打算使用rnk=2etc 来获得每个id.

4

2 回答 2

11

语法应如下所示:

SELECT RANK() OVER(PARTITION BY a.id ORDER BY a.timestamp) AS rnk
于 2012-05-05T23:40:53.367 回答
2

@dbaseman 的提示工作正常(对您的查询进行了修复):

WITH t AS (
    SELECT *
         , rank() OVER(PARTITION BY id ORDER BY ts) AS rnk
    FROM tbl
) 
SELECT id, ts, area AS area1
FROM   t
WHERE  rnk = 1
ORDER  BY id, ts;

有一个更短的方法:

SELECT DISTINCT
       id
     , nth_value(ts,   1) OVER w  AS ts
     , nth_value(area, 1) OVER w  AS area_n
FROM   tbl
WINDOW w AS (PARTITION BY id ORDER BY ts);

您还必须测试它是否更快。应该执行类似的操作。
手册中有关 PostgreSQL 的窗口函数库的更多信息。

于 2012-05-06T00:25:38.017 回答