PSQL density_rank одного элемента из общего количества элементов
Я могу использовать следующий запрос PSQL (в конце), чтобы получить dense_rank
однако из одной строки в моей таблице я хотел бы иметь возможность отображать это как:
dense_rank OUT OF total distinct ranks
Например, так как dense_rank
с учетом "связей", так сказать, если у меня есть 100 строк, а выбранная строка занимает 14-е место (а есть только 59 различных рангов), я хотел бы сказать:
Ranked 14th out of 59
Есть ли способ, которым я могу изменить свой запрос для достижения этого, или мне придется использовать несколько запросов?
Вот мой запрос:
SELECT ranked.*
FROM
(SELECT id,
postable_id,
spread_count,
bury_count,
read_count,
(spread_count*3) + (bury_count*-2) + (read_count*-1) AS score,
dense_rank() OVER (
ORDER BY (spread_count*3) + (bury_count*-2) + (read_count*-1) DESC) AS RANK
FROM posts) AS ranked
WHERE id = ?
2 ответа
Вы можете попробовать это.
SELECT t.*
FROM (SELECT ranked.*,
RNK||' out of '||MAX(RNK) OVER() as rnk_pos
FROM
(SELECT id,
postable_id,
spread_count,
bury_count,
read_count,
(spread_count*3) + (bury_count*-2) + (read_count*-1) AS score,
dense_rank() OVER (
ORDER BY (spread_count*3) + (bury_count*-2) + (read_count*-1) DESC) AS RNK
FROM posts) AS ranked
) t
WHERE id=?
По сути, вы хотите это:
SELECT p.*
FROM (SELECT p.*
(spread_count*3) + (bury_count*-2) + (read_count*-1) AS score,
dense_rank() OVER (ORDER BY (spread_count*3) + (bury_count*-2) + (read_count*-1) DESC) AS RANK,
count(distinct (spread_count*3) + (bury_count*-2) + (read_count*-1)) over () as outof
FROM posts p
) p
WHERE id = ?;
Увы, это не работает, потому что Postgres не поддерживает COUNT(DISTINCT)
как оконная функция. Вы можете реализовать это с помощью других оконных функций:\
SELECT p.*
FROM (SELECT p.*,
dense_rank() over (order by score desc) AS RANK,
sum( (seqnum = 1)::int) as outof
FROM (SELECT p.*,
(spread_count*3) + (bury_count*-2) + (read_count*-1) AS score,
row_number() over (partition by (spread_count*3) + (bury_count*-2) + (read_count*-1) AS score order by spread_scount) as seqnum
FROM posts p
) p
) p
WHERE id = ?;