我有一张表格如下:
CREATE TABLE results (
id uuid primary key UNIQUE,
score integer NOT NULL
)
我需要选择一个具有特定UUID的记录及其周围的内容(例如,前后5个)按分数排序
SELECT * FROM results
WHERE id = <SOME_UUID>
ORDERED BY score
OFFSET -5 LIMIT 10; -- apparently this is wrong
我怎样才能有效地做到这一点?
答案 0 :(得分:0)
它不是'有效',但你可以试试这个:
select a.* from (SELECT * FROM results
WHERE id <> <SOME_UUID> and score <= (select score from results WHERE id = <SOME_UUID>)
ORDERED BY score,id desc
LIMIT 5) as a
UNION ALL
SELECT * FROM results
WHERE id = <SOME_UUID>
UNION ALL
select b.* from (SELECT * FROM results
WHERE id <> <SOME_UUID> and score >= (select score from results WHERE id = <SOME_UUID>)
ORDERED BY score, id asc
LIMIT 5) as b
我试过这个SQL-Server,它需要'ALL'来计算。 因此,您可能会获得具有相同分数的记录作为重复记录。为避免这种情况,请再次使用子查询并使用select distinct。
答案 1 :(得分:0)
解决此问题的一种方法是使用窗口函数分配每行的等级,然后找出您感兴趣的等级:
WITH ranked AS (
SELECT id, score, rank() OVER (ORDER BY score) AS rnk
FROM results),
this_rank AS (
SELECT rnk - 5 AS low_rnk FROM ranked
WHERE id = <some uuid>::uuid)
SELECT id, score
FROM ranked, this_rank
WHERE rnk >= low_rnk
ORDER BY rnk
LIMIT 11;
对于非常低或高的分数,您获得的行数少于11行,而不是NULL
秒的行。
另一个细节:PRIMARY KEY
已经暗示唯一性,因此您不必在表定义中使用UNIQUE
子句。