有这个表
+-----+------+
| ID|Status|
+-----+------+
| 1| 0|
| 2| 1|
| 3| 1|
| 4| 0|
| 5| 1|
| 6| 1|
| 7| 1|
| 8| 1|
| 9| 0|
| 10| 1|
| 12| 1|
+-----+------+
我想选择Status = 1的ID作为连续值的范围:
+-----+-----+
| Low| High|
+-----+-----+
| 2| 3|
| 5| 8|
| 10| 10|
| 12| 12|
+-----+-----+
我不确定如何处理这个问题。
答案 0 :(得分:2)
您可以通过为每一行分配一个组来完成此操作。一种方法使用相关子查询来计算任何给定的不同状态的数量:
select status, min(id) as low, max(id) as high
from (select t.*,
(select count(*)
from t t2
where t2.id < t.id and t2.status <> t.status
) as grp
from t
) t
group by status, grp;
您可以将where
添加到内部或外部查询,以限制为status = 1
。
编辑:
如果性能是个问题,那么变量会更快。我认为最简单的方法是这里建议的版本 - 计算非1值的数量:
select status, min(id) as low, max(id) as high
from (select t.*,
(@grp := (status <> 1)) as grp
from t cross join
(select @grp := 0) params
order by id
) t
where status = 1
group by status, grp;
这也可以使用t(id, status)
上的索引。
答案 1 :(得分:0)
尝试使用变量和GROUP BY
SELECT MIN(id) AS low ,MAX(id) AS high
FROM
(
SELECT
@row_number:=CASE
WHEN @id = status THEN @row_number
ELSE @row_number + 1
END AS num,
@id:=status as status,
id
FROM tab, (SELECT @row_number:=0, @id := 1) t
ORDER BY id
) t
WHERE t.status = 1
GROUP BY num
答案 2 :(得分:0)
抱歉,误读MySQL for MSSQL。似乎MySQL不支持递归CTE。
使用递归CTE:
declare @data table(
ID int not null primary key,
Status bit not null)
insert into @data
values
(1, 0),
(2, 1),
(3, 1),
(4, 0),
(5, 1),
(6, 1),
(7, 1),
(8, 1),
(9, 0),
(10, 1),
(12, 1)
;
with dataRecursive as(
-- anchor
select data.ID low,
data.ID
from @data data
where data.Status = 1
and
not exists(
select 1
from @data data_previous
where data_previous.Status = 1
and
data_previous.ID = data.ID -1
)
union all
-- recursion
select dataRecursive.low,
data_next.ID
from @data data_next
inner join
dataRecursive
on dataRecursive.ID = data_next.ID - 1
where data_next.Status = 1
)
select low,
MAX(ID) as high
from dataRecursive
group by low
order by low