按线程路径和总投票数订购评论

时间:2014-07-02 10:46:07

标签: sql postgresql

我在通过他们的主题路径和每个评论的upvotes数量排序评论时遇到了一些麻烦。

现在他们只按线程路径排序。我试过并搜索了很多东西,但没有结果。

这是我的查询

WITH RECURSIVE first_comments AS (
(
 (
   SELECT id, text, level, parent_id, array[id] AS thread_path, total_votes FROM comments
   WHERE comments."postId" = 1 AND comments."level" = 0 
 )
)
UNION
 (
  SELECT e.id, e.text, e.level, e.parent_id, (fle.thread_path || e.id), e.total_votes
  FROM
  (
    SELECT id, text, level, parent_id, total_votes FROM comments
    WHERE comments."postId" = 1
  ) e, first_comments fle
  WHERE e.parent_id = fle.id
 )
)
SELECT id, text, level, total_votes, thread_path from first_comments ORDER BY 5 ASC

此查询会产生:

--------------------------------------------------
| id  | level  | total_votes |    thread_path    |
--------------------------------------------------
| 1   |   0    |      5      |  {1}              |
| 3   |   1    |      9      |  {1,3}            |
| 7   |   2    |      5      |  {1,3,7}          |
| 9   |   2    |      7      |  {1,3,9}          |
| 11  |   3    |      0      |  {1,3,9,11}       |
| 12  |   4    |      0      |  {1,3,9,11,12}    |
| 13  |   5    |      0      |  {1,3,9,11,12,13} |
| 10  |   1    |     20      |  {1,10}           |
| 2   |   0    |     10      |  {2}              |
| 6   |   1    |      1      |  {2,6}            |
| 4   |   0    |      8      |  {4}              |
| 8   |   1    |      6      |  {4,8}            |
| 5   |   0    |      3      |  {5}              |
--------------------------------------------------

结果应为

--------------------------------------------------
| id  | level  | total_votes |    thread_path    |
--------------------------------------------------
| 2   |   0    |     10      |  {2}              |
| 6   |   1    |      1      |  {2,6}            |
| 4   |   0    |      8      |  {4}              |
| 8   |   1    |      6      |  {4,8}            |
| 1   |   0    |      5      |  {1}              |
| 10  |   1    |     20      |  {1,10}           |              
| 3   |   1    |      9      |  {1,3}            |
| 9   |   2    |      7      |  {1,3,9}          |
| 11  |   3    |      0      |  {1,3,9,11}       |
| 12  |   4    |      0      |  {1,3,9,11,12}    |
| 13  |   5    |      0      |  {1,3,9,11,12,13} |
| 7   |   2    |      5      |  {1,3,7}          |
| 5   |   0    |      3      |  {5}              |
--------------------------------------------------

我在这里缺少什么......?

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

只需在路径旁边累积另一个数组,其中不仅包含其路径中每条注释的id,还包含每个ID之前的total_votes(作为负数)。之后,您可以按该列订购。

WITH RECURSIVE first_comments AS (
(
 (
   SELECT id, text, level, parent_id, array[id] AS path, total_votes,
          array[-total_votes, id] AS path_and_votes
   FROM comments
   WHERE comments."postId" = 1 AND comments."level" = 0 
 )
)
UNION
 (
  SELECT e.id, e.text, e.level, e.parent_id, (fle.path || e.id), e.total_votes,
         (fle.path_and_votes || -e.total_votes || e.id)
  FROM
  (
    SELECT id, text, level, parent_id, total_votes FROM comments
    WHERE comments."postId" = 1
  ) e, first_comments fle
  WHERE e.parent_id = fle.id
 )
)
SELECT id, text, level, total_votes, path from first_comments ORDER BY path_and_votes ASC

SQLFiddle(仅限数据 - 没有递归CTE)

答案 1 :(得分:0)

您想按最高级别的总票数进行排序。我想我会通过使用窗口函数来解决这个问题。

而不是:

SELECT id, text, level, total_votes, path
from first_comments
ORDER BY 5 ASC;

由路径明确排序。试试这个:

select id, text, level, total_votes,
       max(total_votes) over (partition by path[1]) as toplevel_votes
from first_comments
order by 6 desc;

这会计算最高级别的总票数,并将其用于订购。