AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 47585
Accepted
Royi Namir
Royi Namir
Asked: 2013-08-06 11:05:08 +0800 CST2013-08-06 11:05:08 +0800 CST 2013-08-06 11:05:08 +0800 CST

CTE 查询没有打印出正确的结构?

  • 772

我有这张代表层次结构的表:

childID  parentID          NAME          siblingOrder
1          1               a               0
212        1               ab              1
112        1               ac              2
412        1               ad              3
-912       112             aca             0

结构是:

a
+----ab
+----ac
     +---aca
+----ad

(该siblingOrder列用于控制ab, ac,的顺序ad )

我已经有了这个解决方案,它使用 siblingOrder:

;WITH CTE AS(
   SELECT childID, parentID, 0 AS depth, NAME , siblingOrder,
         CAST(RIGHT('00000' + CAST(siblingOrder AS VARCHAR(6)), 6)  AS VARCHAR(1024))  AS PATH
   FROM   @myTable
   WHERE   childID = parentID 
    UNION ALL
    SELECT  TBL.childID, TBL.parentID,
           CTE.depth + 1 , TBL.name ,TBL.siblingOrder,
           CAST(cte.Path + '.' + RIGHT('00000' + CAST(Tbl.siblingOrder AS VARCHAR(6)), 6)AS VARCHAR(1024) )
    FROM   @myTable AS TBL
            INNER JOIN CTE  ON  TBL.parentID = CTE.childID
    WHERE   TBL.childID<>TBL.parentID
)
SELECT path,depth, childID, parentID, siblingOrder, REPLICATE('----', depth) + name
FROM CTE
  ORDER BY PATH

所以order by PATH实际上做的工作:

在此处输入图像描述

问题:

问题是我必须(!)将值放入siblingOrder以使其工作!

否则,例如:

如果我把0所有siblingOrder这些都放在结果中:

在此处输入图像描述

(是的,现在按路径排序 - 不起作用......)

我需要它aca永远在ac

(我添加的唯一原因siblingOrder是订购兄弟姐妹!)而且我不想siblingOrder在不需要时强制添加

问题 :

是否可以增强查询以便siblingOrder只影响兄弟姐妹?

我的意思是,如果我不关心兄弟姐妹的顺序(通过放置0),我仍然aca希望ac

sqlonline : 与 siblingOrder

Sqlonline - 没有 siblingOrder

sql-server cte
  • 1 1 个回答
  • 517 Views

1 个回答

  • Voted
  1. Best Answer
    Sebastian Meine
    2013-08-06T11:14:53+08:002013-08-06T11:14:53+08:00

    您需要在路径中包含parentID和。childID所以而不是

    RIGHT('00000' + CAST(Tbl.siblingOrder AS VARCHAR(6)), 6)
    

    你应该写

    RIGHT('0000000000' + CAST(Tbl.parentID AS VARCHAR(10)), 10) + RIGHT('00000' + CAST(Tbl.siblingOrder AS VARCHAR(6)), 6) + RIGHT('0000000000' + CAST(Tbl.childID AS VARCHAR(10)), 10)
    

    (那是在你的代码中的两个地方)

    通过这种方式,您可以在需要的地方提供 siblingOrder。如果存在,它将覆盖子订单。如果不存在,孩子将按其 childID 排序。

    没有 siblingOrder 的SQL Fiddle

    MS SQL Server 2008 架构设置:

    CREATE TABLE dbo.MyTable
        ([childID] int, [parentID] int, [NAME] varchar(3), [siblingOrder] int)
    ;
    
    INSERT INTO dbo.MyTable
        ([childID], [parentID], [NAME], [siblingOrder])
    VALUES
        (1, 1, 'a', 0),
        (212, 1, 'ab', 0),
        (112, 1, 'ac', 0),
        (412, 1, 'ad', 0),
        (-912, 112, 'aca', 0)
    ;
    

    查询 1:

    ;WITH CTE AS(
       SELECT childID, parentID, 0 AS depth, NAME , siblingOrder,
             CAST(RIGHT('0000000000' + CAST(parentID AS VARCHAR(10)), 10) + RIGHT('00000' + CAST(siblingOrder AS VARCHAR(6)), 6)+ RIGHT('0000000000' + CAST(childID AS VARCHAR(10)), 10)  AS VARCHAR(1024))  AS PATH
       FROM   dbo.MyTable 
       WHERE   childID = parentID 
        UNION ALL
        SELECT  TBL.childID, TBL.parentID,
               CTE.depth + 1 , TBL.name ,TBL.siblingOrder,
               CAST(cte.Path + '.' + RIGHT('0000000000' + CAST(Tbl.parentID AS VARCHAR(10)), 10) + RIGHT('00000' + CAST(Tbl.siblingOrder AS VARCHAR(6)), 6)+ RIGHT('0000000000' + CAST(Tbl.childID AS VARCHAR(10)), 10) AS VARCHAR(1024) )
        FROM   dbo.MyTable AS TBL
                INNER JOIN CTE  ON  TBL.parentID = CTE.childID
        WHERE   TBL.childID<>TBL.parentID
    )
    SELECT path,depth, childID, parentID, siblingOrder, REPLICATE('----', depth) + name
    FROM CTE
      ORDER BY PATH
    

    结果:

    |                                                                             PATH | DEPTH | CHILDID | PARENTID | SIBLINGORDER |    COLUMN_5 |
    ----------------------------------------------------------------------------------------------------------------------------------------------
    |                                                       00000000010000000000000001 |     0 |       1 |        1 |            0 |           a |
    |                            00000000010000000000000001.00000000010000000000000112 |     1 |     112 |        1 |            0 |      ----ac |
    | 00000000010000000000000001.00000000010000000000000112.0000000112000000000000-912 |     2 |    -912 |      112 |            0 | --------aca |
    |                            00000000010000000000000001.00000000010000000000000212 |     1 |     212 |        1 |            0 |      ----ab |
    |                            00000000010000000000000001.00000000010000000000000412 |     1 |     412 |        1 |            0 |      ----ad |
    

    SQL Fiddle与 siblingOrder

    MS SQL Server 2008 架构设置:

    CREATE TABLE dbo.MyTable
        ([childID] int, [parentID] int, [NAME] varchar(3), [siblingOrder] int)
    ;
    
    INSERT INTO dbo.MyTable
        ([childID], [parentID], [NAME], [siblingOrder])
    VALUES
        (1, 1, 'a', 0),
        (212, 1, 'ab', 1),
        (112, 1, 'ac', 3),
        (412, 1, 'ad', 2),
        (-912, 112, 'aca', 0)
    ;
    

    查询 1:

    ;WITH CTE AS(
       SELECT childID, parentID, 0 AS depth, NAME , siblingOrder,
             CAST(RIGHT('0000000000' + CAST(parentID AS VARCHAR(10)), 10) + RIGHT('00000' + CAST(siblingOrder AS VARCHAR(6)), 6)+ RIGHT('0000000000' + CAST(childID AS VARCHAR(10)), 10)  AS VARCHAR(1024))  AS PATH
       FROM   dbo.MyTable 
       WHERE   childID = parentID 
        UNION ALL
        SELECT  TBL.childID, TBL.parentID,
               CTE.depth + 1 , TBL.name ,TBL.siblingOrder,
               CAST(cte.Path + '.' + RIGHT('0000000000' + CAST(Tbl.parentID AS VARCHAR(10)), 10) + RIGHT('00000' + CAST(Tbl.siblingOrder AS VARCHAR(6)), 6)+ RIGHT('0000000000' + CAST(Tbl.childID AS VARCHAR(10)), 10) AS VARCHAR(1024) )
        FROM   dbo.MyTable AS TBL
                INNER JOIN CTE  ON  TBL.parentID = CTE.childID
        WHERE   TBL.childID<>TBL.parentID
    )
    SELECT path,depth, childID, parentID, siblingOrder, REPLICATE('----', depth) + name
    FROM CTE
      ORDER BY PATH
    

    结果:

    |                                                                             PATH | DEPTH | CHILDID | PARENTID | SIBLINGORDER |    COLUMN_5 |
    ----------------------------------------------------------------------------------------------------------------------------------------------
    |                                                       00000000010000000000000001 |     0 |       1 |        1 |            0 |           a |
    |                            00000000010000000000000001.00000000010000010000000212 |     1 |     212 |        1 |            1 |      ----ab |
    |                            00000000010000000000000001.00000000010000020000000412 |     1 |     412 |        1 |            2 |      ----ad |
    |                            00000000010000000000000001.00000000010000030000000112 |     1 |     112 |        1 |            3 |      ----ac |
    | 00000000010000000000000001.00000000010000030000000112.0000000112000000000000-912 |     2 |    -912 |      112 |            0 | --------aca |
    
    • 6

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve