tsql - 从一列中提取分层数据

标签 tsql sql-server-2012 hierarchical-data

我有以下示例数据:

enter image description here

它基本上显示以下层次结构:

enter image description here

我应该像这样从中得到所有 (S)tart (E)nd 对(顺序不重要):

enter image description here

我的解决方案是推送“Source”表变量中的所有值:

  1. 选择所有连续的 (S)tart (E)nd 对
  2. 将它们插入“目标”表变量
  3. 从“Source”表变量中删除它们
  4. 如果“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')

最佳答案

有点复杂,但试试这个:

;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

关于tsql - 从一列中提取分层数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21882283/

相关文章:

reporting-services - 在图表中的类别组上使用前 n 个

mysql - 这些 SQL 闭包表示例有什么区别?

SQL 获取所有类别和所有子类别

sql - T-SQL 通过入站变量拉取特定月份的数据

mysql - 选择记录条件随机#MySQL

sql - 对 XML 节点中的每个元素进行计数,而不是连续计数

sql - 如何在我的 TSQL 中替换 union all

sql-server - sql - 根据是 parent 还是 child 来计算列

sql - SSMS 2012 : Convert DATETIME to Excel serial number

mysql - SQL数据库设计,递归父子关系?