返回从多个到多个连接的独特组合

时间:2012-10-09 09:17:18

标签: sql sql-server-2008 hierarchy

我有一个包含以下数据的层次结构表:

SOURCE  TARGET  Level   ID
0       1       1       1
0       2       1       2
2       3       2       3
2       4       2       4
2       5       2       5
1       3       2       6
1       4       2       7
1       5       2       8
5       3       3       9
5       3       3       10
4       3       3       11
4       3       3       12
3       6       3       13
3       6       3       14
3       6       4       15
3       6       4       16
3       6       4       17
3       6       4       18

SOURCE和TARGET行是原始数据,用于连接父母和孩子。例如,第三行(LEVEL 2上的SOURCE 2,TARGET 3)连接到第二行(LEVEL 1上的SOURCE 0,TARGET 2),因为第一行的Source等于第二行的目标。
最后使用ROW_NUMBER函数添加ID列,用于为每一行提供唯一的ID 如果SOURCE被PARENT和TARGET替换为CHILD,可能会更容易理解。

我加入表格以找到“父母”。
我希望每个级别的“源”的每个“实例”都连接到其父级之一。哪些连接起来并不重要,但都需要连接到不同的父母。

最终结果应如下所示:

SOURCE  TARGET  Level   ID   P_ID
0       1       1       1    NULL
0       2       1       2    NULL
2       3       2       3    2
2       4       2       4    2
2       5       2       5    2
1       3       2       6    1
1       4       2       7    1
1       5       2       8    1
5       3       3       9    5
5       3       3       10   8
4       3       3       11   4
4       3       3       12   7
3       6       3       13   3
3       6       3       14   6
3       6       4       15   9
3       6       4       16   10
3       6       4       17   11
3       6       4       18   12

有关如何为此编写好的ms-sql查询的任何建议吗?

1 个答案:

答案 0 :(得分:3)

链接到示例数据和SQL Fiddle

要使用的查询如下。

;with cte as (
  select *,rn=row_number() over (partition by level, target
                                 order by id),
           lc=count(1) over (partition by level, target)
  from tbl
)

select a.*, b.id as parent_id
from cte a
left join cte b on b.level=a.level-1
               and b.target=a.source
               and b.rn=(a.rn-1)%b.lc+1
order by id
  1. 项目按每个级别/目标组合排序
  2. 通过序列将孩子与父母联系起来,但是如果孩子多于父母,则MOD(%)操作员负责返回第一个父母并继续分发