mysql 根据条件合并行

标签 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 - 将一行与其前一行合并,使开始和最后结束在同一行

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/

相关文章:

php - 如何使用 Codeigniter 将具有不同值的输入插入到 mysql 数据库中?

mysql - phpmyadmin多对多关系组合键

PHP 和 Mysql、nl2br 和验证错误

java - MySQL 连接器与 Android Studio

MySql 从同一行的不同列返回多行

php - PHP 和 MySQL 中的日志记录/重定向问题

mysql - 获取好友的所有好友列表

mysql - Docker错误: container id followed by "command not found"

php - Android 上传多张带有文本数据的图像

mysql - SQL:首先显示 future 的记录,然后是其余的。均按 create_date DESC