【问题标题】:SQL Tree Query - WITH RECURSIVE & UNION. How to sort by a second valueSQL 树查询 - WITH RECURSIVE & UNION。如何按第二个值排序
【发布时间】:2021-02-25 15:53:09
【问题描述】:

我有一个树状结构的类别表(见下图)。对于快速的单个查询,我有以下 SQL 来获取完整的树。

WITH RECURSIVE search_tree(id, name, path, position) AS 
(
    SELECT id, name, ARRAY[id], position
    FROM table_name
    WHERE id = id

    UNION ALL

    SELECT table_name.id, table_name.name, path || table_name.id, 
           table_name.position
    FROM search_tree
    JOIN table_name ON table_name.parent_id = search_tree.id
    WHERE NOT table_name.id = ANY(path)
)
SELECT id, name, path, position
FROM search_tree 
ORDER BY path

此查询结果如下表

id  | name         | path    | position
----+--------------+---------+-------------
  1 | Cat Pictures | {1}.    |.    0
  2 | Funny        | {1,2}.  |.    0
  3 | LOLCats      | {1,2,3} |.    1
  4 | Animated     | {1,2,4} |.    2
  5 | Classic      | {1,2,5} |.    0
  6 | Renaissance  | {1,6}   |.    1

所以根据路径排序效果很好。但我需要的是根据列位置的顺序,如果路径级别是同一级别(如 id 2 & 4 和 3、4、5)。

因此 ID 的顺序需要是

ids: 1, 6, 2, 5, 3, 4

如何更改我的 SQL 语句以反映该顺序?

【问题讨论】:

    标签: sql sorting tree


    【解决方案1】:

    可以这样实现https://www.db-fiddle.com/f/rpFiPjKSwHW88C4cp6o9Rm/0

    with recursive search_tree(id, parentPath, name) as (
        select id, cast(row_number() over(order by pos) as text), name
        from objects
        where parent_id = 0
    union all
        select o.id, concat(search_tree.parentPath, ',', cast(row_number() over(order by o.pos) as text)), o.name
        from search_tree
        join objects as o on search_tree.id = o.parent_id
    )
    select *
    from search_tree
    order by parentPath;
    

    【讨论】:

    • 这不起作用。这将导致顺序为 1、2、6、5、3、4。这将破坏此递归/联合所有的整个目的,从而为您提供树结构。有没有办法按路径排序,但总是排除最后一个条目?这可能是最好的方法,但我不是 SQL 专家。
    • 所以我不太了解您的要求。 2 和 6 是相同的路径级别,因此根据答案中的列位置进行排序。为什么 6 先于 2?
    • 通过正确的顺序,很容易显示类别结构,因为它们完美排列,只需一次调用数据库(而不是每个类别级别调用一次)。查看下面的此页面以获取更多详细信息(这也是我查询的来源)。但我想更进一步。如果属性具有相同的 parent_id,我希望能够控制列表中的位置。谢谢你的帮助。很高兴再次支持您的答案。 hashrocket.com/blog/posts/recursive-sql-in-activerecord
    • 好的,我明白了。我改变了答案。这会起作用,但是当您想要遵循 id 顺序 1、6、2、5、3、4 时,您需要更改节点 2 和 6 的位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 2018-10-07
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多