使用mysql查询找到具有特定值的4个连续行

时间:2017-03-20 09:51:05

标签: mysql

我的表有4列:id(自动增量),机器(1到300之间的整数),事件(整数),状态(字符串)

我需要在这个表上运行一个查询,它返回具有最低机器号的四台机器,其中event =" 5"和状态="免费"这是连续的数字。

例如,如果机器3忙,查询不应返回1,2,4,5,因为它们不是结果。相反,如果机器4,5,6,7是免费的,它应该返回那些。它不应该返回5,6,7,8,因为它不是最低的机器编号。最低的是4,5,6,7。

select * from mytable where event="5" and status="free" order by machine asc limit 4

正是我需要的,除了它确实返回所有行,而不考虑它们必须在机器列中结果。

可以这样做吗?

sample data as requested:

id - machine - event - status
22      1        5      free
23      2        5      free
24      3        5      busy
25      4        5      busy
26      5        5      free  *
27      6        5      free  *
28      7        5      free  *
29      8        5      free  *
30      9        5      free
31      10       5      busy
32      11       5      free

标有*的行是我需要的行。列机器上的前4个连续行,状态值为free,事件id = 5。

3 个答案:

答案 0 :(得分:1)

如果我理解正确,这应该可以解决问题

select  t1.id, t2.id, t3.id, t4.id
from    (select * from mytable where event="5" and status="free") t1
join    (select * from mytable where event="5" and status="free") t2
on      t1.id + 1 = t2.id
join    (select * from mytable where event="5" and status="free") t3
on      t1.id + 2 = t3.id
join    (select * from mytable where event="5" and status="free") t4
on      t1.id + 3 = t4.id
order by t1.id
limit 1

可能需要对连接条件进行一些调整(没有示例很难说)。

答案 1 :(得分:1)

这样的事情应该有效

    SELECT SUBSTRING_INDEX(GROUP_CONCAT(machine ORDER BY machine),',',4) as machines FROM
(SELECT machine,
CASE WHEN machine=@machine + 1 THEN @n ELSE @n:=@n+1 END AS g,
    @machine := machine As m
  FROM
    t, (SELECT @n:=0) r, (SELECT @machine := '') z
WHERE event=5 and status="free"
  ORDER BY
    id) sub
    GROUP BY g 
    HAVING COUNT(*) >=4

如果你想要所有行

SELECT t.id,t.machine,t.event,t.status FROM
(SELECT id,machine,event,status,GROUP_CONCAT(id ORDER BY id) gr FROM
(SELECT *,
CASE WHEN machine=@machine + 1 THEN @n ELSE @n:=@n+1 END AS g,
    @machine := machine As m
  FROM
    t, (SELECT @n:=0) r, (SELECT @machine := '') z
WHERE event=5 and status="free"
  ORDER BY
    id) sub
    GROUP BY g 
    HAVING COUNT(*) >=4) o
JOIN t ON FIND_IN_SET(t.id,gr)
ORDER BY id LIMIT 4

Test

Test2

答案 2 :(得分:0)

这取决于数据集的大小,但对于小数据集,这应该有效:

select * from mytable m1 where m1.event="5" and m1.status="free" 
and(m1.machine-1 in (select machine from mytable where event="5" and status="free") 
and m1.machine-2 in (select machine from mytable where event="5" and status="free") 
and m1.machine-3 in (select machine from mytable where event="5" and status="free") 
OR( m1.machine+1 in (select machine from mytable where event="5" and status="free") 
and m1.machine+2 in (select machine from mytable where event="5" and status="free") 
and m1.machine+3 in (select machine from mytable where event="5" and status="free") )
order by m1.machine asc limit 4

对于较大的数据集,您将需要使用JOIN来完成相同的操作。

您也可以使用后半部分找到第一个实例,然后从那里开始查询。