假设我有一个表,看起来像这样:
| id | category_id | created_at |
| 1 | 3 | date... |
| 2 | 4 | date... |
| 3 | 1 | date... |
| 4 | 2 | date... |
| 5 | 5 | date... |
| 6 | 6 | date... |想象一下有更多的条目。我想以一种新鲜的方式获取它们,所以按created_at DESC对它们进行排序-但我也想按类别对它们进行分组,每组3个!
因此,在伪代码中,它看起来像这样:
Go to category 1
-> Pick last 3
Go to category 2
-> Pick last 3
Go to category 3
-> Pick last 3以此类推,当没有其他类别可用时,从category_id 1开始。这将被分页,以及,所以我需要使它与偏移和限制以及以某种方式工作。
我根本不确定从哪里开始,也不知道谷歌的关键字是什么。我很乐意在正确的方向上做一些微调,这样我就可以自己找到答案,或者是一个完整的答案。
发布于 2014-08-18 21:05:19
window function row_number()的另一个案例。
每个类别仅最新的3行
SELECT id, category_id, created_at
FROM (
SELECT id, category_id, created_at
, row_number() OVER (PARTITION BY category_id
ORDER BY created_at DESC) AS rn
FROM tbl
) sub
WHERE rn < 4
ORDER BY category_id, rn;每个类别的最新3行,加上后面的行
如果您想要追加其余行(您的问题变得模糊,如果以及如何):
SELECT *
FROM (
SELECT id, category_id, created_at
, row_number() OVER (PARTITION BY category_id
ORDER BY created_at DESC) AS rn
FROM tbl
) sub
ORDER BY (rn > 3), category_id, rn;可以按boolean表达式(rn > 3)的结果进行排序
FALSE (0)
TRUE (1)
NULL (因为默认值为NULLS LAST -此处不适用)
这样,每个类别的最新3行排在第一位,其余的排在后面。
或使用CTE和UNION ALL
WITH cte AS (
SELECT id, category_id, created_at
, row_number() OVER (PARTITION BY category_id
ORDER BY created_at DESC) AS rn
FROM tbl
)
)
SELECT id, category_id, created_at
FROM cte
WHERE rn < 4
ORDER BY category_id, rn
)
UNION ALL
)
SELECT id, category_id, created_at
FROM cte
WHERE rn >= 4
ORDER BY category_id, rn
);同样的结果。
在UNION查询的各个分支中附加ORDER BY所需的所有括号。
https://stackoverflow.com/questions/25363999
复制相似问题