【问题标题】:Selecting a map table of a father-son table选择父子表的映射表
【发布时间】:2011-09-15 18:23:41
【问题描述】:


我有一个父子关系的类别表,看起来像这样:

表名:

tblCategories

列:

猫ID
catFatherID - 此列与 catID 有关系

我需要通过以下方式为每个类别选择它是整个家庭的孩子(包括它自己):
原始表格行:

| catID | catFatherID |
= = = = = = = = = = = =
|   1   | null        |
|   2   |  1          |
|   3   |  1          |
|   4   |  2          |
|   5   |  3          |
|   6   |  4          |

我想得到什么:

| Category ID | Family Category ID |
= = = = = = = = = = = = = =  = = = =
| 1 | 1 | (Yes, I want it to include itself in the return family members)
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 1 | 6 |
| 2 | 2 |
| 2 | 4 |
| 2 | 6 |
| 3 | 3 |
| 3 | 5 |
| 4 | 4 |
| 4 | 6 |
| 5 | 5 |
| 6 | 6 |

问我是否解释得不够充分。

【问题讨论】:

    标签: sql database sql-server-2008 recursive-query


    【解决方案1】:

    CTE 可以很好地解决这个问题。诀窍是在执行 CTE 时保留 root ID。

    SQL 语句

    ;WITH q AS (
      SELECT  root = catID, catID, catFatherID
      FROM    tblCategories
      UNION ALL
      SELECT  q.root, c.catID, c.catFatherID
      FROM    q 
              INNER JOIN tblCategories c ON c.catFatherID = q.catID 
    
    )
    SELECT  root, catID
    FROM    q
    ORDER BY
            root, catID
    

    测试脚本

    ;WITH tblCategories (catID, catFatherID) AS (
      SELECT  1, NULL
      UNION ALL SELECT 2, 1
      UNION ALL SELECT 3, 1
      UNION ALL SELECT 4, 2
      UNION ALL SELECT 5, 3
      UNION ALL SELECT 6, 4
    )
    , q AS (
      SELECT  root = catID, catID, catFatherID
      FROM    tblCategories
      UNION ALL
      SELECT  q.root, c.catID, c.catFatherID
      FROM    q 
              INNER JOIN tblCategories c ON c.catFatherID = q.catID 
    
    )
    SELECT  root, catID
    FROM    q
    ORDER BY
            root, catID
    

    【讨论】:

      【解决方案2】:

      您应该在 CTE 中使用递归 SQL。

      with families(id, parent_id) as (
        select * from tblCategories where id = __initial_id__
        union all
        select t.* from tblCategories as t inner join families as f on t.catFatherID = f.id 
      )
       select * from families
      

      article at MSDN

      【讨论】:

      • 您应该保留 parentId 并在最终结果中选择它。以目前的形式,这不会返回 OP 询问的内容。
      【解决方案3】:
      WITH n(catId, catFatherId) AS 
         (SELECT catId, catFatherId 
          FROM tblCategories 
              UNION ALL
          SELECT n1.catId, n1.catFatherId 
          FROM tblCategories as n1, n
          WHERE n.catId = n1.catFatherId)
      SELECT * FROM n
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-18
        • 2015-02-27
        • 1970-01-01
        • 1970-01-01
        • 2011-11-15
        • 2016-10-16
        • 2012-11-15
        • 1970-01-01
        相关资源
        最近更新 更多