Sql server 无光标排序/合并

Sql server 无光标排序/合并,sql-server,sorting,cursor,Sql Server,Sorting,Cursor,在不使用游标的情况下,我尝试编写T-SQL代码来完成以下任务: 在下表中 SourceData 它有两列,[ColA]和[ColB],其中都是nvarchar(255),具有以下示例数据: ColA | ColB ================== AAA | TripleA TripleA | AAA AAA | ThreeAs ThreeAs | AAA BBB | TripleB TripleB | BBB BBB | ThreeB

在不使用游标的情况下,我尝试编写T-SQL代码来完成以下任务:

在下表中

SourceData
它有两列,
[ColA]
[ColB]
,其中都是
nvarchar(255)
,具有以下示例数据:

ColA    |  ColB
==================
AAA     |  TripleA
TripleA |  AAA
AAA     |  ThreeAs
ThreeAs |  AAA
BBB     |  TripleB
TripleB |  BBB
BBB     |  ThreeBs
ThreeBs |  BBB
等等,

将行数据提取到两个表中

TableA\u根目录
,和
TableB\u子目录

其中
TableA\u Root
有以下列:
[ROID identity],[Root]

TableB\u Children
有以下列:
[COID identity]、[fKey\u ROID]、[Child]

使生成的表具有如下示例数据:

TableA_Root
==============
1  |  AAA
2  |  BBB

TableB_Children
===============
1 | 1 | TripleA
2 | 1 | ThreeAs
3 | 2 | TripleB
4 | 2 | ThreeBs

起初,我想我会使用光标。但是,我确信,这不是最佳方法。显然,这是一种排序和合并,我可以在SQL之外完成。我曾经尝试过使用“IN”或“EXISTS”来处理子查询的一些想法,但是我的尝试没有成功。我可以使用一个新的视角。

假设SourceData上有一个主键,您不能有同一行的副本,那么这将得到您想要的

With    cte1 As
(
        Select  Row_Number() Over (Order By ph) As ph, 
                ColA, 
                ColB
        From   (Select  1 As ph, 
                        ColA,
                        ColB
                From    SourceData) As n
)
Insert  TableA_Root (ROID, Root)
Select  Row_Number() Over (Order By c.ph) As ROID,
        ColA
From    cte1 c
Where   Not Exists (Select  1
                    From    cte1 c2
                    Where   c.ColA = c2.ColB
                    And     c.ph > c2.ph);

Insert  TableB_Children (COID, ROID, Child)
Select  Row_Number() Over (Order By ta.ROID), 
        ta.ROID, 
        tb.Colb
From    TableA_Root ta
Join    SourceData tb
        On  ta.Root = tb.ColA;

你怎么知道
AAA
在根表中,而不是子表中?给定这两行
{AAA,TripleA}
{TripleA,AAA}
你怎么能将“AAA”识别为根而不是TripleA?哦,我希望根可以被定义为在ColB中存在不止一次的任何东西。表中的第一个有点危险,因为没有一个订单一个订单是不能保证的。这里使用了我提到的假设。注意:由于某些原因,SQLFiddle不会同时输出这两个结果,但它可以在SSMS@NW7US是啊,提琴棒极了。顺便说一句,如果你在我的名字前面放一个
@
,我会通过收件箱收到通知。请参见“非常聪明”:使用行号创建所需的OID。我想我会进行某种aOID>bOID比较。我只是不能完全到达那里。使用此技术后,我确实在源数据中发现了一些新特性,但是,有了这些结果,我现在可以进入最终形式(这是一个XML同义词表,将包含在我的MSSQL 2012数据库中,与CONTAINS…FORMSOF一起使用——非常感谢您在这方面花费的时间和精力。顺便说一句:我意识到,在我最初的帖子中,我混合了隐喻。根应该有叶节点,子节点应该有父节点。我认为您在
INSERT
。另外,如果你想避免
SELECT 1 as ph
和内联视图
n
你可以做
ROW\u NUMBER OVER(ORDER BY(SELECT NULL))
这很好。我不知道你可以在ROW\u NUMBER()ORDER BY中摆脱它。很酷。“Into”“插入后”是可选的。与其说是执行,不如说是可读性。因为懒惰,我总是把它省略掉。