最近在看MySQL技术内幕:SQL编程时,发现里面提到了一个关于连续区间的经典问题,首先生成测试数据,目的是想查询出RANK表中,所有ID的连续区间
书中提供的方法很巧妙,首先利用MySQL中的变量计算出行号,由于行号是连续的,所以连续的数值与行号的差值就是一个常量,当出现数值不连续时,差值就会变大,利用这点,我们可以根据差值分组计算连续区间,计算的sql如下
SELECT
MIN(ID) AS START_VALUE,
MAX(ID) AS END_VALUE
FROM
(SELECT ID,@RN := @RN + 1, ID-@RN AS DIFF FROM RANK, (SELECT @RN := 0) AS A) AS B
GROUP BY
DIFF
同时书中也留下了一个问题,如何计算不连续区间,本人想到一个办法,同样也是利用MySQL中的变量,但是需要3个变量,不连续区间开始值,不连续区间结束值,上一列的ID值,用于与当前列比较计算是否是不连续区间,详细sql如下
SELECT START_VALUE, END_VALUE
FROM (SELECT ID,
CASE
WHEN @PREV <> ID - 1 THEN
@START_VALUE := @PREV + 1
ELSE
@START_VALUE := NULL
END AS START_VALUE,
CASE
WHEN @PREV <> ID - 1 THEN
@END_VALUE := ID - 1
ELSE
@END_VALUE := NULL
END AS END_VALUE,
@PREV := ID
FROM RANK,
(SELECT @PREV := NULL, @START_VALUE := 0, @END_VALUE := 0) AS A) AS B
WHERE START_VALUE IS NOT NULL
ORDER BY CAST(START_VALUE AS UNSIGNED)
首先判断上一列的ID是否等于当前列的ID值减一,如果不等那么说明上一列是上一个连续区间的结束,当前列是新连续区间的开始,所以不连续区间的开始值为上一列ID值加1,结束之为当前列ID值减一,如果上一列的ID时候等于当前列的ID值减一,那么说明是连续区间,开始值和结束值都不赋值,之后再通过一个子查询限定开始值不为空就可以查询出不连续区间了
按照上面的思路也可以计算出连续区间,设置两个变量,上一列的ID值和连续区间开始值,首次判断时,由于上一列ID值初始值为NULL,所以会执行ELSE的语句,将第一列的ID值赋给连续区间开始值,接下来开始判断,如果上一列的ID等于当前列的ID值减一那么说明是连续区间,连续区间开始值不变,如果不等说明是新的区间,将当前列的ID值赋给连续区间开始值,由于连续区间的开始值是相同的,所以根据这个值分组即可求出表中的连续区间了
以上就是本人的关于连续区间的一些方法了,大家如果有更好的方法欢迎在评论中留言