查询以获取IDx中的IDy范围

时间:2014-05-16 23:59:47

标签: sql

我有两张桌子:表A就像 IDx ColumnA ColumnB ColumnC

表B就是这样的 IDy IDx ColumnD ColumnE ColumnF

一个IDy只能在一个IDx下。但是一个IDx可以包含许多IDys。一个IDx中的IDys可能连续也可能不连续。

例如,表B可能是

IDy IDx |
 6    10 |
 5    10 |
 17   10 |
 8    10 |
 9    10 |
 18   10 |
 27   10 |
 38   10 |
 39   10 |
 7    10 |
 40   12 |
 37   10 |
 36   20 |
...   ...

如果用户给出IDx为10且批量大小为3,我应该返回IDx 10的所有范围,大于3.对于这种情况,它应该返回

IDx RangeStart RangeEnd
10   5            9
10   37           39    (Since IDy 40 is for IDx 12 and IDy 36 is for IDx 20)

我想要实现的结果中的最后一个灰色区域。例如,在原始表(第一个灰色区域)中,对于IDx 10,它具有4个连续范围,5-9,17-18,27,37-39。仅适用于范围5-9和37-39,尺寸大于或等于批量大小3(用户输入)。所以在结果中,它返回范围开始,范围结束为(5,9和37 39)

我还不清楚如何编写查询,我需要尽可能快地运行查询。有什么建议吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

如果我理解得很好,你会尝试获得至少3个连续值的组 由于没有指定您正在使用的SQLServer版本,我认为它是SQLServer 2012或更高版本 在这种情况下,一种可能性是

WITH A AS (
  SELECT IDx, IDy
       , NextY = LEAD(IDy, 1, IDy)
                 OVER (Partition BY IDx ORDER BY IDy)
  FROM   tableB
), B AS (
  SELECT IDx
       , IDy
       , NextY
       , block = SUM(CASE WHEN IDy + 1 = NextY THEN 0 ELSE 1 END)
                 OVER (Partition BY IDx ORDER BY IDy)
  FROM   A
)
SELECT IDx
     , RangeStart = Min(IDy)
     , RangeEnd = Max(NextY)
FROM   B
WHERE  IDy + 1 = NextY
GROUP BY IDx, Block
HAVING Count(1) >= (3- 1)

SQLFiddle demo

CTE的划分只是为了便于阅读 第一个CTE为同一个IDx添加一个具有下一个IDy值的字段 第二个在表格中创建排名,例如对于具有连续值块的所有行将是相同的 主查询使用排名对数据进行分组。 HAVING条件为2而不是3,因为第二行中MAX(NextY)的值是序列中的第三行,因为NextY是下一个值id IDy,WHERE条件删除了序列被破坏的行。