【问题标题】:Tree view using SQL Query使用 SQL 查询的树视图
【发布时间】:2021-02-23 10:06:32
【问题描述】:

我有一个区域表,我想要一个树视图(表简单排序为树)是否可以使用 sql 查询帮助表示赞赏,我尝试使用自连接来实现,但我没有得到想要的结果。

树视图是这样的

个人

  • Div1
    • Zon1
  • div2
    • zon2
  • div3
    • zon3

编辑:

根据 Charles Bretana 的建议,我在下面的查询中尝试了 CTE,但它没有给我想要的结果。

WITH Emp_CTE (id, ParentID, name)
AS (
SELECT id, ParentID, name
FROM eQPortal_Region
WHERE ParentID=0
UNION ALL
SELECT e.id, e.ParentID, e.name
FROM eQPortal_Region e
INNER JOIN Emp_CTE ecte ON ecte.id = e.ParentID
)
SELECT *
FROM Emp_CTE
GO

这是结果..出了什么问题?

InDiv1

  • Div1
  • Div2
  • Div3
    • Zon3
    • Zon2
    • zon1

【问题讨论】:

  • 什么 rdbms?? Sql server 具有可以执行此操作的公用表表达式 (CTE)。否则,您需要将代码编码到固定的预定数量的级别。可以吗?
  • 是的 .. Microsoft SQL Server .. 好的,让我检查一下 CTE .. 谢谢 ..
  • CTE 没有帮助,请参考我的编辑

标签: sql join treeview common-table-expression self


【解决方案1】:

这家伙Maulik Dhorajia完美地回答了这个问题......

http://maulikdhorajia.blogspot.com/2012/06/sql-server-using-ctecommon-table.html

制作了查询的副本..

;WITH CTECompany
AS
(
    SELECT 
    ID, 
    ParentID, 
    Name , 
    0 AS HLevel,
    CAST(RIGHT(REPLICATE('_',5) +  CONVERT(VARCHAR(20),ID),20) AS VARCHAR(MAX)) AS OrderByField
FROM Region
WHERE ParentID = 0

UNION ALL

SELECT 
    C.ID, 
    C.ParentID, 
    C.Name , 
    (CTE.HLevel + 1) AS HLevel,
    CTE.OrderByField + CAST(RIGHT(REPLICATE('_',5) +  CONVERT(VARCHAR(20),C.ID),20) AS VARCHAR(MAX)) AS OrderByField
FROM Region C
INNER JOIN CTECompany CTE ON CTE.ID = C.ParentID
WHERE C.ParentID IS NOT NULL


)

-- Working Example
SELECT 
ID
, ParentID
, HLevel
, Name
, (REPLICATE( '----' , HLevel ) + Name) AS Hierachy
FROM CTECompany
ORDER BY OrderByField

【讨论】:

  • 自过去 2 小时以来,我一直在尝试回答。但是 OP 自己找到了解决方案。
【解决方案2】:

请参阅以下示例 SQL 脚本:

DECLARE @lV NCHAR(1)=NCHAR(9474),@lR NCHAR(1)=NCHAR(9500),@lU NCHAR(1)=NCHAR(9492),@spc NCHAR(1)=' ';
WITH data AS(SELECT * FROM(VALUES(1,'0','In Div1',1),(2,'1','Div1',1),(3,'2','zon1',1),(4,'1','Div2',2),(5,'1','Div3',3),(6,'4','Zon2',1),(7,'5','Zon3',1))t([ID],[ParentID],[Name],[SeqOrder])
),d_root AS(SELECT CAST('/'AS NVARCHAR(MAX))[n_path],* FROM data WHERE ParentID='0'
),d_cte AS(SELECT b.n_path+CAST(ROW_NUMBER()OVER(ORDER BY a.ID)AS NVARCHAR(MAX))+'/'[n_path],a.* FROM data a INNER JOIN d_root b ON a.ParentID=b.ID UNION ALL SELECT b.n_path+CAST(ROW_NUMBER()OVER(ORDER BY a.ID)AS NVARCHAR(MAX))+'/'[n_path],a.* FROM data A INNER JOIN d_cte b ON a.ParentID=b.ID
),Tree_BASE AS (SELECT CAST(n_path AS HIERARCHYID)[h_id],* FROM d_root UNION ALL SELECT CAST(n_path AS HIERARCHYID)[h_id],* FROM d_cte
),cte_o AS(SELECT a.h_id,CASE WHEN EXISTS(SELECT * FROM Tree_BASE WHERE h_id>b.h_id AND h_id.GetAncestor(1)=b.h_id.GetAncestor(1))THEN @lV ELSE @spc END[t_l] FROM Tree_BASE a INNER JOIN Tree_BASE b ON a.h_id.IsDescendantOf(b.h_id)=1 AND NOT b.h_id=HIERARCHYID::GetRoot()
),cte_m AS(SELECT x.*,(SELECT t_l+'' FROM cte_o WHERE h_id=x.h_id FOR XML PATH(''))[b_tree] FROM Tree_BASE x
),cte_h AS(SELECT ISNULL(LEFT(b_tree,LEN(b_tree)-1)+CASE WHEN EXISTS(SELECT * FROM Tree_BASE WHERE h_id>a.h_id AND h_id.GetAncestor(1)=a.h_id.GetAncestor(1))THEN @lR ELSE @lU END,'')+' '+RTRIM(Name) [TreeV],a.h_id FROM cte_m a
)SELECT b.TreeV,ROW_NUMBER()OVER(ORDER BY a.h_id ASC)[row_id]FROM Tree_BASE a INNER JOIN cte_h b ON a.h_id=b.h_id ORDER BY row_id

【讨论】:

    猜你喜欢
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    相关资源
    最近更新 更多