2

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

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 行是原始数据,用于连接父母和孩子。例如,第三行(源 2,级别 2 上的目标 3)连接到第二行(源 0,级别 1 上的目标 2),因为第一行的源等于第二行的目标。
ID 列使用 ROW_NUMBER 函数添加到末尾,用于为每一行提供唯一 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 查询有什么建议吗?

4

1 回答 1

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 (%) 运算符负责返回第一个父节点并继续分配
于 2012-10-09T09:34:41.610 回答