我如何将下面使用变量的 MySQL 查询转换为 PostgresSQL 查询

问题描述 投票:0回答:2

我是使用 postgresql 的新手,正在寻找有关如何将 MySql 中的这些 vars 用法转换为 Postgres 的帮助,看起来 postgres 不支持这种类型的语法。

select
       name
from
       (
              select
                     @lidx := field(
                            coalesce(
                                   @root_id, coalesce(p10.id,p9.id,p8.id,p7.id,p6.id,p5.id,p4.id,p3.id,p2.id,p1.id)
                            ),
                            p1.id,p2.id,p3.id,p4.id,p5.id,p6.id,p7.id,p8.id,p9.id,p10.id
                     ) as leftmost,
                     concat(
                            if(@lidx >= 10, rpad(p10.name, 24, ' '), ''),
                            if(@lidx >= 9, rpad(p9.name, 24, ' '), ''),
                            if(@lidx >= 8, rpad(p8.name, 24, ' '), ''),
                            if(@lidx >= 7, rpad(p7.name, 24, ' '), ''),
                            if(@lidx >= 6, rpad(p6.name, 24, ' '), ''),
                            if(@lidx >= 5, rpad(p5.name, 24, ' '), ''),
                            if(@lidx >= 4, rpad(p4.name, 24, ' '), ''),
                            if(@lidx >= 3, rpad(p3.name, 24, ' '), ''),
                            if(@lidx >= 2, rpad(p2.name, 24, ' '), ''),
                            rpad(p1.name, 24, ' ')
                     ) as locator,
                     -- Prepend a tab to the name for every level of the tree after the root.
                     concat(repeat('\\t', @lidx - 1), p1.name) as name
              from
                     (
                            -- Declare constants
                            select
                                   -- company_id. Leave null for all companies
                                   @company_id := null,
                                   -- root_id. Leave null for all departments
                                   @root_id := null
                     ) sqlVars,
                     hierarchy p1
                     -- repeatedly left join until the desired max depth (10)
                     left join hierarchy p2 on p2.id = p1.parent_id
                     left join hierarchy p3 on p3.id = p2.parent_id
                     left join hierarchy p4 on p4.id = p3.parent_id
                     left join hierarchy p5 on p5.id = p4.parent_id
                     left join hierarchy p6 on p6.id = p5.parent_id
                     left join hierarchy p7 on p7.id = p6.parent_id
                     left join hierarchy p8 on p8.id = p7.parent_id
                     left join hierarchy p9 on p9.id = p8.parent_id
                     left join hierarchy p10 on p10.id = p9.parent_id
              where
                     (      -- filter on company_id if non null
                            @company_id is null
                            or @company_id = p1.company_id
                     )
                     and (  -- filter on root_id if non null
                            @root_id is null
                            or @root_id in (p1.id,p2.id,p3.id,p4.id,p5.id,p6.id,p7.id,p8.id,p9.id,p10.id)
                     )
              -- alpha ordering
              order by 
                     locator
       ) flattened;

要检查当前的 SQL 和使用情况并运行它,请使用下面的 sql fiddle

SQL Fiddle[1]:http://sqlfiddle.com/#!9/faf62e/200

sql postgresql hierarchical-data recursive-query
2个回答
1
投票

您可以使用递归查询:

with recursive tree as (
  select name, id, 0 as level
  from hierarchy 
  where parent_id is null
  union all
  select c.name, c.id, p.level + 1
  from hierarchy c
    join tree p on p.id = c.parent_id
) 
search depth first by name set sort_order
select repeat(' ', level * 2)||name
from tree
order by sort_order;

通过使用

search depth first
,我们可以将子树保持在一起。

请注意,我使用空格来实现缩进,因为 dbFiddle 中未显示制表符。

在线示例


0
投票

接近:

with recursive tree (id, name, level) as (
  select id, name, 0 from hierarchy where parent_id is null
  union all
  select hierarchy.id, hierarchy.name, tree.level+1
  from hierarchy join tree on hierarchy.parent_id = tree.id
)
select repeat('\t', level) || name from tree order by id;

SQLFiddle

它不会重现与您的 sqlfiddle 完全相同的行顺序,但这是在 PostgreSQL(或 MySQL 8.0)中进行递归查询的方法。

阅读手册以获取有关递归 CTE 语法的更多信息:https://www.postgresql.org/docs/current/queries-with.html#QUERIES-WITH-RECURSIVE

© www.soinside.com 2019 - 2024. All rights reserved.