没有光标的排序/合并

时间:2013-02-07 22:06:36

标签: 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     |  ThreeBs
ThreeBs |  BBB

等,

将行数据提取到两个表中,

TableA_RootTableB_Children

其中TableA_Root包含以下列:[ROID identity], [Root]

TableB_Children包含以下列:[COID identity],[fKey_ROID],[Child]

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

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

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

起初,我以为我会使用Cursor。但是,我确信这不是最佳方法。显然,这是一种排序和合并,我可以在SQL之外做。我使用“IN”或“EXISTS”尝试子查询的一些想法,但我的尝试不尽如人意。我可以用一个全新的视角。

1 个答案:

答案 0 :(得分:2)

假设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;