1

コメントシステムを書いています。ここのチュートリアルに従って階層を取得できました( http://www.postgresonline.com/journal/archives/173-Using-LTree-to-Represent-and-Query-Hierarchy-and-Tree-Structures.html )

    SELECT n.node_path          AS PATH,
           n.note_id            AS _1,
           n.note_no            AS _2,
           n.public_key         AS _3,
           n.upvotes            AS _4
    FROM public.comment_table AS n
             INNER JOIN public.comment_table AS a ON (a.node_path @> n.node_path)
    GROUP BY _1, PATH
    ORDER BY PATH

ただし、賛成票で行を注文するのに問題があります。ORDER BY PATH, n.upvotes同じスレッドの返信には異なるnode paths. node_pathsを使用して計算されpublic_keyます。

与えられた例から

a (0 upvotes)
-> b (0 upvotes)
-> c (1 upvote)
d (1 upvote)
-> e (0 upvotes)

のノード パスはbそれぞれおよびcになります。ノードパスとそれらから単純に and を差し引くことはできません。私がそうすると、次の順序になります。a.ba.cbcORDER BY

a
d
-> b
-> c
-> e

public_keyから各行を削除するnode_pathと、単純に短い順に並べ替えられるため、これは理にかなっていますnode_path

正しい階層になり、次のように賛成票でソートされるクエリを作成するにはどうすればよいですか。

d (1)
-> e (0)
a (0)
-> c (1)
-> b (0)
4

1 に答える 1

2

賛成票の数が絶えず変化しており、ltree再帰を避けるためにルートをたどったと仮定すると、皮肉なことに再帰を必要としないこれに対する解決策は考えられません結果そのもの。

with recursive base as (
  select node_path, upvotes, 
         array[row_number() over (order by upvotes desc, node_path)] as sort_path
    from comment_table 
   where nlevel(node_path) = 1
  union all
  select c.node_path, c.upvotes, 
         p.sort_path||row_number() over (order by c.upvotes desc, c.node_path)
    from base p
    join comment_table c 
      on subpath(c.node_path, 0, -1) = p.node_path
)
select * from base order by sort_path;

 node_path | upvotes | sort_path 
-----------+---------+-----------
 d         |       1 | {1}
 d.e       |       0 | {1,3}
 a         |       0 | {2}
 a.c       |       1 | {2,1}
 a.b       |       0 | {2,2}
(5 rows)
于 2020-07-24T14:51:06.310 に答える