我有一个像这样的值表
978412, 400
978813, 20
978834, 50
981001, 20
如您所见,第二个数字添加到第一个数字是序列中下一个数字之前的 1 个数字。最后一个数字不在范围内(不遵循直接顺序,如在下一个值中)。我需要的是一个 CTE(是的,理想情况下),它将输出这个
978412, 472
981001, 20
第一行包含范围的起始编号,然后是其中节点的总和。下一行是下一个范围,在此示例中与原始数据相同。
我有一个像这样的值表
978412, 400
978813, 20
978834, 50
981001, 20
如您所见,第二个数字添加到第一个数字是序列中下一个数字之前的 1 个数字。最后一个数字不在范围内(不遵循直接顺序,如在下一个值中)。我需要的是一个 CTE(是的,理想情况下),它将输出这个
978412, 472
981001, 20
第一行包含范围的起始编号,然后是其中节点的总和。下一行是下一个范围,在此示例中与原始数据相同。
从 Josh 发布的文章中,这是我的看法(经过测试和工作):
SELECT
MAX(t1.gapID) as gapID,
t2.gapID-MAX(t1.gapID)+t2.gapSize as gapSize
-- max(t1) is the specific lower bound of t2 because of the group by.
FROM
( -- t1 is the lower boundary of an island.
SELECT gapID
FROM gaps tbl1
WHERE
NOT EXISTS(
SELECT *
FROM gaps tbl2
WHERE tbl1.gapID = tbl2.gapID + tbl2.gapSize + 1
)
) t1
INNER JOIN ( -- t2 is the upper boundary of an island.
SELECT gapID, gapSize
FROM gaps tbl1
WHERE
NOT EXISTS(
SELECT * FROM gaps tbl2
WHERE tbl2.gapID = tbl1.gapID + tbl1.gapSize + 1
)
) t2 ON t1.gapID <= t2.gapID -- For all t1, we get all bigger t2 and opposite.
GROUP BY t2.gapID, t2.gapSize
查看这篇MSDN 文章。它为您的问题提供了一个解决方案,它是否适合您取决于您拥有的数据量和您对查询的性能要求。
很好地使用查询中的示例,并使用他的最后一个解决方案获取岛屿的第二种方法(第一种方法导致 SQL 2005 出现错误)。
SELECT MIN(start) AS startGroup, endGroup, (endgroup-min(start) +1) as NumNodes
FROM (SELECT g1.gapID AS start,
(SELECT min(g2.gapID) FROM #gaps g2
WHERE g2.gapID >= g1.gapID and NOT EXISTS
(SELECT * FROM #gaps g3
WHERE g3.gapID - g2.gapID = 1)) as endGroup
FROM #gaps g1) T1 GROUP BY endGroup
我添加的是(endgroup-min(start) +1) as NumNodes
. 这会给你计数。