选择从指定值开始直到另一个指定值的行

Lin*_*ink 8 sql-server-2008 sql-server gaps-and-islands

我有一个包含多列的表,想要检查列值,选择该列值之后的行,直到出现单独的列值。我试过使用BETWEEN,但如果列值是整数,它只查找整数之间的数字。

例如,如果我有一张这样的表:

id 时间值 
t1 12:00 PM 15
t1 12:02 下午 4
t1 12:03PM 7
t1 12:05PM 16
t5 下午 12:10 250
t5 12:15 下午 15
t8 上午 11:00 15
t8 下午 3:00 2
t8 下午 3:05 100
t2 7:00 PM 15
t2 7:01 下午 16
t15 5:00AM 35 

我想获取值 15 和 16 之间的行。基本上,如果我可以按id,然后time,并收集 15 出现后的行,直到在同一id. 如果没有值 16,例如我想要接下来的 100 行,然后搜索下一个值 15。

我希望查询返回这个:

id 时间值 
t1 12:00 PM 15
t1 12:02 下午 4
t1 12:03PM 7
t1 12:05PM 16
t2 7:00 PM 15
t2 7:01 下午 16
t5 12:15 下午 15
t8 上午 11:00 15
t8 下午 3:00 2
t8 下午 3:05 100

这可能令人困惑。我试过了:

SELECT * FROM table WHERE value BETWEEN '15' AND '16' ORDER BY id, time
Run Code Online (Sandbox Code Playgroud)

作为起点,但它只返回值为 15 或 16 的行,因为它们是整数。

我想到id那时对表格进行排序time。这些条目是通过另一个系统自动添加的,因此我正在尝试查询表中的特定值范围。

有任何想法吗?

澄清:

如果我有15, 1, 16, 7, 15, 2, 16相同的行id,我会想要两个“岛”:15, 1, 16, 15, 2, 16

ype*_*eᵀᴹ 7

应该在 2008 版本中工作的建议。

reextester.com 上测试:

with 
  end_points as                       -- find start and end points
    ( select id, time, value
      from table_x
      where value in (15, 16)
    ), 
  start_points as                     -- only the start points
    ( select id, time, value
      from end_points
      where value = 15
    )
select 
    t.id, t.time, t.value
from
    start_points as s
  outer apply                         -- find where each island ends
    ( select top (1) ep.* 
      from end_points as ep
      where s.id   = ep.id
        and s.time < ep.time
      order by ep.time
    ) as e
  cross apply                         -- and run through each island
    ( select p.id, p.time, p.value, 
             rn = row_number() over (order by p.time) 
      from table_x as p
      where s.id   = p.id
        and s.time <= p.time
        and         ( p.time < e.time
                   or p.time = e.time and e.value = 16
                   or          e.time is null)
    ) as t
where 
    t.rn <= 100
order by
    t.id, t.time  ;
Run Code Online (Sandbox Code Playgroud)

更多信息: