带分组的SQL查询

时间:2012-02-23 10:51:14

标签: sql postgresql

我正在使用postgresql并想知道我是否可以在一个请求中执行此操作: 我有一个包含四列的表:id,start,end和user_id 在一个请求中,我做了一个

SELECT sum(finish - start) as duration, user_id group by user_id

现在,如果我将所提取的行的ID保存在某处也会很棒,因为我稍后需要它们 这有可能吗? 非常感谢

3 个答案:

答案 0 :(得分:3)

您应该查看Window Functions and Partitionsarray_agg

假设这个例子:

CREATE TABLE mytable (
    id SERIAL PRIMARY KEY,
    user_id INTEGER,
    start INTEGER,
    finish INTEGER
);
INSERT INTO mytable(id, user_id, start, finish) VALUES (1, 1, 5, 10);  -- duration: 5
INSERT INTO mytable(id, user_id, start, finish) VALUES (2, 2, 10, 30); -- duration: 20
INSERT INTO mytable(id, user_id, start, finish) VALUES (3, 1, 15, 20); -- duration: 5

如您所知,SELECT SUM(finish - start), user_id FROM mytable GROUP BY user_id将返回:

10  | 1
20  | 2

我认为你不想要的是这个查询的输出(因为如果你在GROUP BY中使用一个具有唯一非空约束的列,你可能不会使用聚合,因为我假设{ {1}}是):id

使用窗口功能,您可以使用与当前行相关的其他行的数据。

以下查询:

SELECT id, SUM(finish - start), user_id FROM mytable GROUP BY user_id, id

产生这些结果:

SELECT id, SUM(finish - start) OVER (PARTITION BY user_id) AS duration, user_id
    FROM mytable ORDER BY user_id

现在,每个1 | 10 | 1 3 | 10 | 1 2 | 20 | 2 使用一行,但id适用于窗口框架内的整个行集(此处,所有具有相同SUM的行当前行。)

就您的应用程序而言,您可能需要逐个读取行并将user_id的相关值存储在某处,直到id更改。

或者,您可以使用array_agg将所有ID聚合到一个数组中:

user_id

例如,如果您希望将其放在以空格分隔的字符串中,请在此基础上使用array_to_string

SELECT array_agg(id), SUM(finish - start) AS duration, user_id
    FROM mytable GROUP BY user_id ORDER BY user_id, duration


{1, 3}  | 10 | 1
{2}     | 20 | 2

答案 1 :(得分:1)

如果你想要一个字符串作为结果(不是数组),那么你可以在PostgreSQL 9.0或更高版本中使用string_agg()来简化任务

SELECT user_id
     , sum(finish - start) AS duration
     , string_agg(id, ', ') AS ids
FROM   tbl
GROUP  BY 1
ORDER  BY 1

答案 2 :(得分:0)

假设id是行ID,你试过这个吗?

SELECT id, sum(finish - start) as duration, user_id group by id, user_id