我有以下示例数据:
它基本上显示以下层次结构:
我应该从中得到所有(S)挞(E)和这样的对(顺序并不重要):
我的解决方案是推送“Source”表变量中的所有值:
我的问题是有人想出替代解决方案吗?在我的实际情况中,我有更多行,我担心删除和插入表变量。
以下脚本生成示例数据:
DECLARE @DataSource TABLE
(
[ID] TINYINT
,[Type] CHAR(1)
)
INSERT INTO @DataSource ([ID], [Type])
VALUES (3,'S')
,(6,'E')
,(7,'S')
,(10,'S')
,(13,'E')
,(14,'E')
,(15,'S')
,(16,'S')
,(17,'S')
,(19,'S')
,(20,'S')
,(26,'E')
,(27,'E')
,(28,'E')
,(29,'E')
,(30,'E')
,(31,'S')
,(32,'S')
,(35,'E')
,(36,'S')
,(38,'E')
,(39,'S')
,(40,'S')
,(44,'E')
,(45,'E')
,(46,'E')
答案 0 :(得分:1)
这有点复杂,但试试这个:
;with a as
(
select [ID], [Type], row_number() over (order by ID) rn from @DataSource
), b as
(
select [ID], [Type], rn, cast(1 as int) lvl from a where rn = 1
union all
select a.[ID], a.[Type],a.rn, case when a.[Type] = 'S' then 1 when a.[Type] = 'E' then -1 else 0 end + lvl
from a
join b on a.rn = b.rn + 1
),
c as
(
select [ID], [Type], row_number() over (partition by [type] order by lvl,rn) grp
from b
)
select c1.id S, c2.id E from c c1
join c c2
on c1.grp = c2.grp
where c1.[type] = 'S' and c2.[type] = 'E'
order by c1.id
option( maxrecursion 0)
结果:
S E
3 6
7 14
10 13
15 30
16 29
17 28
19 27
20 26
31 46
32 35
36 38
39 45
40 44
编辑:因为您使用的是sqlserver 2012,脚本可以简化,我还添加了性能改进。我希望这适用于你的情况。脚本现在假设'S'总是在'E'之前。
;with a as
(
select [ID], [Type],
sum(case when [type]='S' then 1 when [type]='E' then -1 end)over(order by id) lvl
from @DataSource
), b as
(
select [ID], [Type],
row_number() over (partition by [type] order by lvl,id) grp
from a
)
select min(id) S, max(id) E
from b
group by grp
order by s