使用CTE以正确的顺序获取父元素和子元素[关闭]

问题描述 投票:-6回答:2

我的CTE查询需要一些帮助。我的表存储了使用4个键字段的程序的菜单项,GUID是每个菜单项的ID。父级是每个菜单项的父级的ID。如果GUID和父级相同,则它是一个根元素。级别确定菜单在0中是哪个级别是root,在第一个子级别中是1,依此类推。位置指定是其父级别内的排序顺序。

这是我到目前为止所拥有的,但是并没有按照我想要的方式排序

WITH

cteReports (guid, name, description, parent, level, position)
AS
(

SELECT guid, name, description, parent, level, position
FROM dbo.tbl_crmmenu
WHERE guid = parent

UNION ALL

 SELECT e.guid, e.name, e.description, e.parent, e.level, 
      r.level + 1
    FROM tbl_crmmenu e
      INNER JOIN cteReports r
        ON e.parent = r.guid
)
SELECT
  guid, name, description, parent, level, position
  FROM dbo.tbl_crmmenu

这里是一些示例数据的链接https://www.dropbox.com/s/txatxblnyw4a77c/sample.csv?dl=0

这里是示例数据的DDLhttps://www.dropbox.com/s/holehyas99xp6tv/Sample%20Data%20DDL.sql?dl=0

这就是我想要的结果

enter image description here

sql-server recursive-query
2个回答
0
投票
;with MyCTE1 as (
  select
    [guid], [name], [description], parent, [level], position,
    CAST(position AS VARCHAR(4096)) AS Sorter,
    CONVERT(varbinary(max),[guid]) as [Path]
  from tbl_crmmenu
  where [guid] = Parent

  union all

  select
    t.[guid], t.[name], t.[description], t.parent, t.[level], t.position,
    CAST(MyCTE1.Sorter + 'a' AS VARCHAR(4096)) AS Sorter,
    [Path] + CONVERT(binary(16),t.[guid])
  from MyCTE1
  join tbl_crmmenu t on MyCTE1.[guid] = t.Parent and t.[level] <> 0
)
select *
from MyCTE1
ORDER BY MyCTE1.Sorter, MyCTE1.position

-1
投票

这不是最有效的解决方案,但是它将满足您的要求。

create table tbl_crmmenu
(
  guid varchar(10),
  name varchar(10),
  description varchar(10),
  parent varchar(10),
  level int,
  position int
);

insert into tbl_crmmenu
  values 
  ('A', 'A', 'A', 'A', 0, 0),
  ('A1', 'A1', 'A1', 'A', 1, 0),
  ('A2', 'A2', 'A2', 'A', 1, 1),
  ('A11', 'A11', 'A11', 'A1', 2, 0),
  ('A12', 'A12', 'A12', 'A1', 2, 1),
  ('A111', 'A111', 'A111', 'A11', 3, 0),
  ('A121', 'A121', 'A121', 'A12', 3, 0),
  ('B', 'B', 'B', 'B', 0, 1),
  ('B1', 'B1', 'B1', 'B', 1, 0),
  ('B12', 'B12', 'B12', 'B1', 2, 0),
  ('B2', 'B2', 'B2', 'B', 1, 1); 

WITH cteReports (guid, name, description, parent, level, position, path)
AS (    
  SELECT guid, name, description, parent, level, position
    , concat(level, format(position, '##0000')) as path
  FROM dbo.tbl_crmmenu
  WHERE guid = parent

  UNION ALL

  SELECT e.guid, e.name, e.description, e.parent, e.level, e.position 
    , concat(r.path, '-', format(r.level+1, '##0000'), format(e.position, '##0000')) as path
  FROM tbl_crmmenu e
  INNER JOIN cteReports r ON e.parent = r.guid
  where e.guid <> r.guid
)
SELECT
  guid, name, description, parent, level, position, path
FROM cteReports
order by path;
© www.soinside.com 2019 - 2024. All rights reserved.