我有以下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
然而,这导致group by date子句不起作用(即不总结特定日期所有锻炼的持续时间)。我认为这是因为对于具有多个记录的日期,您不能拥有一个ID。即使返回的特定记录有多个与之相关的训练,有没有办法返回ID?
例如,如果昨天有人进行了3次训练,每次训练持续时间为40分钟,则查询将返回120分钟(给定日期的持续时间总和),然后还会返回该日期锻炼的每个ID?
或者我不应该在查询本身中这样做,只是在应用程序中执行此操作?
感谢您的帮助。
答案 0 :(得分: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 :(得分: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
答案 2 :(得分: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
这将添加另一列,即当天的总数。
答案 3 :(得分: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)