mysql在条件上组合行

时间:2013-05-31 08:41:36

标签: mysql

我有一张表:

user | area | start | end
 1       1     12     18
 1       1     19     27
 1       1     29     55 
 1       1     80     99

表示:“用户”从“开始”到“时间”结束时出现在“区域”中,区域可以重叠。

我想要的是获得如下结果:

user | start-end
 1      12-18,19-27,29-55
 1      80-99

表示:组合出现的时间差小于指定值,即(row2.start - row1.end< 10),一个结果行代表用户区域的一次“访问”。 目前,我可以通过使用一个sql语句比较同一个表来区分每次访问并获得访问次数。但我无法找到获得上述结果的方法。 任何帮助表示赞赏。

说明:出现的前3个只链接在一起,因为:row2.start-row1.end< 10和row3.start-row2.end< 10,最后出现的是一次新访问,因为:80(row4.start) - 55(row3.end)> = 10.

1 个答案:

答案 0 :(得分:1)

我们需要两个步骤:

1 - 将一行与其前驱者相结合,使其在同一行中具有开始和结尾

SELECT
  user, area, start, end, @lastend AS lastend, @lastend:=end AS ignoreme
FROM 
  tablename, 
  (SELECT @lastend:=0) AS init
ORDER BY user, area, start, end;

2 - 使用差异作为分组标准

SELECT
  ...
FROM
  ...
  (SELECT @groupnum:=0) AS groupinit
GROUP BY
  ... ,
  IF(start-lastend>=10,@groupnum:=@groupnum+1,@groupnum)

现在让我们把它结合起来:

SELECT
  user, area,
  GROUP_CONCAT(CONCAT(start,"-",end)) AS start_end
FROM (
    SELECT
      user, area, start, end, @lastend AS lastend, @lastend:=end AS ignoreme
    FROM 
      tablename, 
      (SELECT @lastend:=0) AS init
    ORDER BY user, area, start, end
 ) AS baseview,
 (SELECT @groupnum:=0) AS groupinit
GROUP BY
  user, area,
  IF(start-lastend>=10,@groupnum:=@groupnum+1,@groupnum)

修改

修正了错别字并经过验证:SQLfiddle