我有两张桌子:表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)
我还不清楚如何编写查询,我需要尽可能快地运行查询。有什么建议吗?
谢谢!
答案 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)
CTE
的划分只是为了便于阅读
第一个CTE
为同一个IDx添加一个具有下一个IDy值的字段
第二个在表格中创建排名,例如对于具有连续值块的所有行将是相同的
主查询使用排名对数据进行分组。 HAVING
条件为2而不是3,因为第二行中MAX(NextY)
的值是序列中的第三行,因为NextY是下一个值id IDy,WHERE
条件删除了序列被破坏的行。