我正在使用postgresql并想知道我是否可以在一个请求中执行此操作: 我有一个包含四列的表:id,start,end和user_id 在一个请求中,我做了一个
SELECT sum(finish - start) as duration, user_id group by user_id
现在,如果我将所提取的行的ID保存在某处也会很棒,因为我稍后需要它们 这有可能吗? 非常感谢
答案 0 :(得分:3)
您应该查看Window Functions and Partitions或array_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