0

我有以下 SQL 查询:

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?

还是我不应该在查询本身中执行此操作而只在应用程序中执行此操作?

谢谢你的帮助。

4

4 回答 4

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

这将添加另一列,即当天的总数。

于 2013-05-08T21:34:27.797 回答
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,即使是那些没有锻炼的 ID,那么您可以使用 LEFT JOIN。

于 2013-05-08T21:32:48.930 回答
1

MySQL 有 group_concat(id) ,但您一般会询问“sql”。

编辑:对于 postgresql,我发现Postgresql GROUP_CONCAT 等效?

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
于 2013-05-08T21:33:19.920 回答
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)
于 2013-05-09T19:27:40.903 回答