我有一个像这样的表:
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 - 将一行与其前一行合并,使开始和最后结束在同一行
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
关于mysql 根据条件合并行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16853241/