我有一张表:
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.
答案 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