2013-05-08 73 views
0

我有以下SQL查詢:總和(列)和按日期分組,但獲得該日期的所有ID?

SELECT date(created_at), sum(duration) as total_duration 
FROM "workouts" WHERE "workouts"."user_id" = 5 AND "workouts"."category" = 'All' 
GROUP BY date(created_at) ORDER BY date(created_at) ASC 

,但我也想查詢鍛鍊的ID,所以我想這:

SELECT id as id, date(created_at), sum(duration) as total_duration 
FROM "workouts" WHERE "workouts"."user_id" = 5 AND "workouts"."category" = 'All' 
GROUP BY id, date(created_at) ORDER BY date(created_at) ASC 

但是,這導致該組中按日期條款不起作用(即不在特定日期總結所有訓練的持續時間)。我認爲這是因爲對於有多個記錄的日期你不能有一個ID。即使返回的特定記錄有多個與之關聯的鍛鍊,是否有任何方法可以返回ID?例如,如果某人昨天完成了3次鍛鍊,每次鍛鍊持續40分鐘,則查詢將返回120分鐘(總計給定日期的持續時間),然後還返回該日期的鍛鍊的每個ID ?

或者我不應該在查詢本身做這件事,只是在應用程序中做?

感謝您的任何幫助。

+0

你正在使用什麼數據庫? – 2013-05-08 21:32:15

+0

Postgresql 9.2.3 – kwyoung11 2013-05-08 21:32:47

回答

0

儘管@flaschenpost和@Gordon Linoff的回答非常有幫助,但我最終需要兩方面的答案。

下面是我的查詢結束:

SELECT array_agg(id) OVER (PARTITION BY date(created_at)) as ids, date(created_at), sum(load_volume) OVER (PARTITION BY date(created_at)) as total_load_volume 
FROM "workouts" WHERE "workouts"."user_id" = 5 AND "workouts"."category" = 'All' 
GROUP BY date(created_at), id, load_volume ORDER BY date(created_at) ASC; 

爲了獲得每次鍛鍊的ID,如果有多個鍛鍊,在我需要使用ARRAY_AGG以及窗函數在給定的日期。這是輸出:

        ids   | date | total_load_volume 
------------------------------------------------+------------+------------------- 
{30}           | 2013-04-20 |    400 
{29}           | 2013-04-23 |    400 
{31}           | 2013-04-24 |    400 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{33,34,35,36,37,38,41,42,43,44,45,46,47,48,49} | 2013-04-28 |    1732 
{50}           | 2013-04-30 |    400 
{51}           | 2013-05-07 |    400 
(20 rows) 
1

您應該能夠使用子查詢得到的結果:

SELECT w1.id, 
    w2.created_at 
    coalesce(w2.total_duration, 0) total_duration 
FROM "workouts" w1 
INNER JOIN 
(
    SELECT date(created_at) created_at, 
    sum(duration) as total_duration 
    FROM "workouts" 
    WHERE "workouts"."user_id" = 5 
    AND "workouts"."category" = 'All' 
    GROUP BY date(created_at) 
) w2 
    on w1.created_at = w2.created_at 
ORDER BY w2.created_at; 

如果你想返回所有的ID,甚至那些沒有鍛鍊,那麼你可以使用LEFT JOIN。

1

MySQL對此有group_concat(id),但是您一般會詢問「sql」。

編輯:對於PostgreSQL我發現Postgresql GROUP_CONCAT equivalent?

SELECT array_agg(id) as id_array, date(created_at), sum(duration) as total_duration 
FROM "workouts" WHERE "workouts"."user_id" = 5 AND "workouts"."category" = 'All' 
GROUP BY date(created_at) ORDER BY date(created_at) ASC 
1

您可以使用Windows功能如下:

SELECT id as id, date(created_at), sum(duration) as total_duration, 
     sum(sum(duration)) over (partition by date(created_at)) as DaysTotal 
FROM "workouts" 
WHERE "workouts"."user_id" = 5 AND "workouts"."category" = 'All' 
GROUP BY id, date(created_at) 
ORDER BY date(created_at) ASC 

這將添加另一列是總的一天。