【问题标题】:Best way to filter hierarchical data using T-SQL?使用 T-SQL 过滤分层数据的最佳方法?
【发布时间】:2009-07-01 16:37:29
【问题描述】:

Table1 有一个项目列表。 表 2 有一个项目可以关联的组列表。 表 3 是 1 和 2 之间的交叉引用。

表 2 中的组以分层方式设置。

Key    ParentKey    Name
1      NULL         TopGroup1
2      NULL         TopGroup2
3      1            MiddleGroup1
4      2            MiddleGroup2
5      3            NextGroup1
6      4            NextGroup1
7      2            MiddleGroup3

我希望能够从由 Table3 过滤的 Table1 中进行选择。
从 Table1 中选择 Table3.ParentKey 不是“2”或其任何后代的项目

从另一个帖子here on stackoverflow 我已经能够使用 CTE 来识别层次结构。

WITH Parent AS
(
    SELECT
        table2.Key,
        cast(table2.Key as varchar(128))  AS Path
    FROM
        table2
    WHERE
        table2.ParentKey IS NULL

   UNION ALL

    SELECT
        TH.Key,
        CONVERT(varchar(128), Parent.Path + ',' + CONVERT(varchar(128),TH.Key)) AS Path
    FROM
        table2 TH
    INNER JOIN
        Parent
    ON
        Parent.Key = TH.ParentKey
)
SELECT * FROM Parent

我想这真的是一个两部分的问题。

  1. 如何过滤上述内容?例如,返回 TopGroup1 不在谱系中的所有组。
  2. 如何将其应用于交叉引用表 1 中的过滤结果。

【问题讨论】:

    标签: sql database tsql


    【解决方案1】:

    关于这个主题有一整本书,见:'Joe Celko's Trees and Hierarchies in SQL for Smarties'

    就个人而言,当我不得不解决这个问题时,我使用了一个临时表来展开层次结构,然后从临时表中选择一些东西。本质上,您可以在单个查询中在临时表中构建另一层,通常层次结构只有 5-10 层深,因此您可以在 5 到 10 个查询中展开它。

    【讨论】:

      【解决方案2】:

      试试这个

      -- Table1 (ItemKey as PK, rest of the columns)
      -- Table2 (as you defined with Key as PK)
      -- Table3 (ItemKey  as FK referencing Table1(ItemKey), 
      --         GroupKey as FK referencing Table2(Key))
      
      Declare @Exclude int
      Set @Exclude = 2          
      ;WITH Groups AS     -- returns keys of groups where key is not equal
      (                   -- to @Exclude or any of his descendants
         SELECT t.Key
           FROM table2 t
          WHERE t.ParentKey IS NULL
            and t.Key <> @Exclude
         UNION ALL
         SELECT th.Key,
           FROM table2 th
          INNER JOIN Groups g ON g.Key = th.ParentKey
          Where th.Key <> @Exclude
      )
      SELECT t1.* 
        FROM Table1 t1
       WHERE t1.key in (Select t3.ItemKey 
                          From table3 t3 
                         Inner Join Groups g2 
                            on t3.GroupKey = g2.Key
                       )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        • 1970-01-01
        • 2022-01-21
        • 1970-01-01
        • 2021-09-24
        相关资源
        最近更新 更多