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 = ?;
Другие вопросы по тегам