MySQL获取两个条件之间的范围的ID

时间:2014-08-28 02:14:02

标签: mysql sql

我们说我有一张桌子

+----+------------+
| id | condition  |
+----+------------+
| 1  | open       |
+----+------------+
| 2  | content    |
+----+------------+
| 3  | content    |
+----+------------+
| 4  | close      |
+----+------------+
| 5  | nocontentx |
+----+------------+
| 6  | nocontenty |
+----+------------+
| 7  | open       |
+----+------------+
| 8  | content    |
+----+------------+
| 9  | close      |
+----+------------+
| 10 | nocontentz |
+----+------------+
| 11 | open       |
+----+------------+
| 12 | content    |
+----+------------+

并希望获得一个新表格,我在其中获取" close"之间的值的ID(第一个和最后一个);和" open"。请注意,这两个条件之间的值是动态的(我无法按"nocontent"whatever搜索)

比如我得到这张表:

+----+----------+--------+
| id | start_id | end_id |
+----+----------+--------+
| 1  | 5        | 6      |
+----+----------+--------+
| 2  | 10       | 10     |
+----+----------+--------+

提前致谢!

http://sqlfiddle.com/#!2/c255c8/2

1 个答案:

答案 0 :(得分:5)

您可以使用相关子查询执行此操作:

select (@rn := @rn + 1) as id,
       id as startid,
       (select id
        from atable a2
        where a2.id > a.id and
              a2.condition = 'close'
        order by a2.id asc
        limit 1
       ) as end_id
from atable a cross join
     (select @rn := 0) vars
where a.condition = 'open';

工作的SQL小提琴是here

注意这也会返回第三个open。如果您不想要它,请将having end_id is not null添加到查询的末尾。

编辑:

如果你知道id是顺序的,你可以在上面的查询中添加和减去1:

select (@rn := @rn + 1) as id,
       id+1 as startid,
       (select id
        from atable a2
        where a2.id > a.id and
              a2.condition = 'open'
        order by a2.id asc
        limit 1
       ) - 1 as end_id
from atable a cross join
     (select @rn := 0) vars
where a.condition = 'close';

您也可以通过不同的方式执行此操作,即通过计算任何给定行之前打开和关闭的数量并将其用作组标识符。数据的结构方式,每个其他组都是您正在寻找的:

select grp, min(id), max(id)
from (select t.*,
             (select sum(t2.condition in ('open', 'close'))
              from t t2
              where t2.id <= t.id
             ) as grp
      from t
     ) t
where t.condition not in ('open', 'close') and
      grp % 2 = 0
group by grp;