获取相关 table 中每行的前 5 行
Get top 5 rows per row in related table
我正在使用 PostgreSQL 9.4.
我有 workout lists
和关联的连接 table 枚举该列表中的锻炼。
我想 return 5 列表中每个 锻炼的最新结果。
下面 return 的每个结果,如果我追加 LIMIT 5
,我总共只得到 5 个结果,而不是每次锻炼 5 个。我如何在 SQL 中执行此操作?
SELECT "results".* FROM "results"
WHERE "results"."user_id" = 1
AND workout_id IN (SELECT workout_id FROM workout_list_join_table
WHERE workout_list_id = 5)
ORDER BY "results"."done_at" DESC
您可以使用 window function:
select *
from (
SELECT results.*,
row_number() over (partition by workout_id order by done_at desc) as rn
FROM results
WHERE results.user_id = 1
AND workout_id IN (SELECT workout_id
FROM workout_list_join_table
WHERE workout_list_id = 5)
) t
where rn <= 5
ORDER BY done_at DESC;
从 9.4 版开始,您还可以使用 LATERAL:
SELECT r.*
FROM workout_list_join_table w
JOIN LATERAL(SELECT * FROM results r WHERE r.workout_id = w.workout_id AND user_id = 1 ORDER BY r.done_at DESC LIMIT 5) r ON (true)
WHERE workout_list_id = 5
ORDER BY
r.done_at DESC;
使用大表时,由于有更好的查询计划,这可能比 window 函数快得多。 LATERAL 不需要所有数据,它可以限制子查询中的行数。查看 Markus Winand 的这些幻灯片以获取更多信息:Modern SQL in PostgreSQL
我正在使用 PostgreSQL 9.4.
我有 workout lists
和关联的连接 table 枚举该列表中的锻炼。
我想 return 5 列表中每个 锻炼的最新结果。
下面 return 的每个结果,如果我追加 LIMIT 5
,我总共只得到 5 个结果,而不是每次锻炼 5 个。我如何在 SQL 中执行此操作?
SELECT "results".* FROM "results"
WHERE "results"."user_id" = 1
AND workout_id IN (SELECT workout_id FROM workout_list_join_table
WHERE workout_list_id = 5)
ORDER BY "results"."done_at" DESC
您可以使用 window function:
select *
from (
SELECT results.*,
row_number() over (partition by workout_id order by done_at desc) as rn
FROM results
WHERE results.user_id = 1
AND workout_id IN (SELECT workout_id
FROM workout_list_join_table
WHERE workout_list_id = 5)
) t
where rn <= 5
ORDER BY done_at DESC;
从 9.4 版开始,您还可以使用 LATERAL:
SELECT r.*
FROM workout_list_join_table w
JOIN LATERAL(SELECT * FROM results r WHERE r.workout_id = w.workout_id AND user_id = 1 ORDER BY r.done_at DESC LIMIT 5) r ON (true)
WHERE workout_list_id = 5
ORDER BY
r.done_at DESC;
使用大表时,由于有更好的查询计划,这可能比 window 函数快得多。 LATERAL 不需要所有数据,它可以限制子查询中的行数。查看 Markus Winand 的这些幻灯片以获取更多信息:Modern SQL in PostgreSQL