Sql 递归查询排序

Sql 递归查询排序,sql,tsql,Sql,Tsql,我有一个标准表,它包含了父、子类别的关系…就像这样 id, parent, catName, sort 我使用下面的查询创建一个递归树 ;WITH cte AS ( SELECT 0 AS lvl, id, catName, parent,levels,sort, CAST(id AS VARCHAR(128)) AS path FROM CategoriesMap WHERE parent =0 UNION ALL SELECT p.lvl +

我有一个标准表,它包含了父、子类别的关系…就像这样

id, parent, catName, sort
我使用下面的查询创建一个递归树

;WITH cte AS (
    SELECT 0 AS lvl, id, catName, parent,levels,sort,
        CAST(id AS VARCHAR(128)) AS path
    FROM CategoriesMap WHERE parent =0
    UNION ALL
    SELECT p.lvl + 1, c.id, c.catName, c.parent,c.levels,c.sort,
        CAST(p.path + '_' + CAST(c.id AS VARCHAR) AS VARCHAR(128))
    FROM CategoriesMap c
    INNER JOIN cte p ON p.id = c.parent
)
SELECT 
    id, 
    catName AS catName, 
    lvl,
    levels,
    path,
    parent,
    sort
FROM cte 
ORDER BY path
输出如下图所示:

查找值为ASP.NET和CLASSIC ASP的行,这些是技术>软件(父级)的最后一个叶(子级),我想对任何给定父级(最后一个父级)的最后一个子级进行排序。我可以为一个给定节点(最后一个子节点)设置多个父节点&我所关心的就是使用“排序”列对最后一个子节点(叶节点)进行排序。

所以基本上,“经典Asp”应该在“Asp.Net”之前(最后一列是我的图片中的排序列)

我的查询很好,它按预期返回结果…唯一的问题是我想使用表中的排序列对最后一个节点进行排序,最后一个节点可以有3个或4个我想排序的子节点,最后一个节点之上的所有节点都是它的父节点(它们的顺序已经正确了)


我想要这样的输出。。。。互联网>ISP>有线电视(1): 正如您所看到的,CableVision和Verizon的排序值为1 &然后2,现在让我们假设我们有购物>优惠券>梅西(0):西尔斯 (2) ,同样的事情……我希望梅西百货和西尔斯百货能被分类……而且它很漂亮 显然,他们的父母正在购物>优惠券

@Richard aka cyberkiwi,在应用了您的代码之后,我对Categories表的排序是非常随机的。产量低于

这应该能满足您的需要。 真正的诀窍是把树叶和树枝混在一起。在我的解决方案中,叶子总是出现在分支之前,在叶子内部(即使与分支相互混合),它们当然是按
排序
列排序的

DDL

质疑


延迟一个级别的
路径
计算,以便最终结果集具有可用的父路径(
ppath
):

;WITH cte AS (
    SELECT 0 AS lvl, id, catName, parent,levels,sort,
        CAST('' AS VARCHAR(128)) AS ppath
    FROM CategoriesMap WHERE parent =0
    UNION ALL
    SELECT p.lvl + 1, c.id, c.catName, c.parent,c.levels,c.sort,
        CAST(p.ppath + '_' + CAST(p.id AS VARCHAR) AS VARCHAR(128))
    FROM CategoriesMap c
    INNER JOIN cte p ON p.id = c.parent
)
SELECT 
    id, 
    catName, 
    lvl,
    levels,
    CAST(ppath + '_' + CAST(id AS VARCHAR) AS VARCHAR(128)) AS path,
    parent,
    sort
FROM cte
ORDER BY 
    CASE WHEN sort IS NULL
           THEN path
           ELSE ppath
    END
  , sort ;
不太清楚上面给出的错误原因。这不会:

ORDER BY 
    CASE WHEN sort IS NULL
      THEN CAST(ppath + '_' + CAST(id AS VARCHAR) AS VARCHAR(128))
      ELSE ppath
    END
  , sort ;

呵呵,我们有着相同的总体想法:)这打破了整个表的排序,我的查询很好,它返回了预期的结果…唯一的挑战是我想使用表中的排序列对最后一个节点进行排序,最后一个节点可以有3或4个子节点,我想排序,最后一个节点之上的所有节点都是它的父节点(它们已经按照正确的顺序排列)是的,我试过了&如果我通过了一个类别,它就会起作用。例如,其中PARENT=12。我想返回所有类别及其子类别。以你为例……所有的父母都在上面,而所有的孩子都在下面。如果查询可以返回树型输出,并且只根据排序列对最后一个叶进行排序,那就太好了。。。。Internet>ISP>CableVision(1):Verizon(2)正如您所看到的CableVision和Verizon的排序值为1,然后是2,现在让我们假设我们有购物>优惠券>Macys(0):西尔斯(2),同样的事情…我希望Macys和西尔斯进行排序…很明显,他们的父母正在购物>优惠券。如果我在parent=12的位置执行此查询,则会起作用(这是技术类别),在我的例子中,parent=0(我返回所有父节点及其子节点)。是的,获取错误:列名“path”无效。我认为只有在我可以将子项放在它们的顶级类别下,我们才能达到目标。无论我想做什么,都有可能吗?我希望在保持父子关系的同时,基于数据库驱动的排序列进行排序。我不介意是否必须更改表/查询设计。我请求o不同意它是随机的。11,13,14都是叶子。它们首先出现在分支之前(1,12是分支的),甚至在它们自己内部进行排序。同样,1_3和1_4出现在1_2_*之前,因为它们是叶子,并且(1_3/1_4是内部排序的)。如果你想让答案给出你所期望的,你需要学会首先说出你所期望的。从最后一张图片开始,不要只告诉我们它是错的。告诉我们它应该是什么样子。如果我无法正确解释,我深表歉意。请查看ID“1”及其排序值(即1),它是一个父类&它应该是顶级父类。ID“2”也应该在ID“3”之前,如果您查看它们的排序列值,您会注意到排序已关闭。我有一种感觉,在您发布一张显示上一张图片中给出的确切示例所需的确切结果的图片之前,您不会看到关于此问题的任何其他操作。
;WITH cte AS (
    SELECT 0 AS lvl, id, catName, parent,levels,sort,
        CAST('' AS VARCHAR(128)) AS ppath
    FROM CategoriesMap WHERE parent =0
    UNION ALL
    SELECT p.lvl + 1, c.id, c.catName, c.parent,c.levels,c.sort,
        CAST(p.ppath + '_' + CAST(p.id AS VARCHAR) AS VARCHAR(128))
    FROM CategoriesMap c
    INNER JOIN cte p ON p.id = c.parent
)
SELECT 
    id, 
    catName, 
    lvl,
    levels,
    CAST(ppath + '_' + CAST(id AS VARCHAR) AS VARCHAR(128)) AS path,
    parent,
    sort
FROM cte
ORDER BY 
    CASE WHEN sort IS NULL
           THEN path
           ELSE ppath
    END
  , sort ;
ORDER BY 
    CASE WHEN sort IS NULL
      THEN CAST(ppath + '_' + CAST(id AS VARCHAR) AS VARCHAR(128))
      ELSE ppath
    END
  , sort ;