我使用PostgreSQL和想知道如果我能做到這一點的一個請求: 我有四列的表:ID,開始,結束和user_id說明 在一個要求,我做了SQL查詢通過
SELECT sum(finish - start) as duration, user_id group by user_id
現在,如果我保存某些地方的獲取行的ID太多了,因爲我在代碼中需要它們以後 這可能嗎? 非常感謝
我使用PostgreSQL和想知道如果我能做到這一點的一個請求: 我有四列的表:ID,開始,結束和user_id說明 在一個要求,我做了SQL查詢通過
SELECT sum(finish - start) as duration, user_id group by user_id
現在,如果我保存某些地方的獲取行的ID太多了,因爲我在代碼中需要它們以後 這可能嗎? 非常感謝
假設id
是行ID,你試過嗎?
SELECT id, sum(finish - start) as duration, user_id group by id, user_id
你應該看看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
中使用具有唯一非空約束的列,則不使用聚合,因爲我假定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
的相關值存儲在某處,直到user_id
發生更改。
或者,你可以使用array_agg
到所有的ID彙總到一個數組:
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
如果,例如,你想這在一個空間分隔的字符串,在此之上使用array_to_string
:
SELECT array_to_string(array_agg(id), ' '), SUM(finish - start) AS duration, user_id
FROM mytable GROUP BY user_id ORDER BY user_id, duration
如果你想要一個字符串作爲結果(不是數組),那麼你就可以在string_agg()
PostgreSQL的9.0簡化任務或更高版本:
SELECT user_id
, sum(finish - start) AS duration
, string_agg(id, ', ') AS ids
FROM tbl
GROUP BY 1
ORDER BY 1
非常感謝布魯諾,這正是我一直在尋找的! – 2012-02-23 11:52:42
@PomponVdp:這似乎是解決您的問題的方法。所以你會投票答覆(如果你還沒有),並接受答案作爲你的問題的最佳解決方案。要做到這一點,請點擊投票櫃檯下的V。 – tscho 2012-02-23 21:21:08