mysql - 确定日期范围是否包含在 MySQL 中的另一个范围中

标签 mysql sql

我正在寻找一种以“干净”的方式执行此操作的方法(不是 3..n 交叉联接),只是想知道是否可以在 sql 中执行此操作,如果不能,我会选择另一个方法解决方案。 为了简化将使用数字而不是日期 我有 n 行,包含 n 个任务和 n 个项目

 task  item   start end
    1     1      1     5
    1     2      2     6
    1     3      0     4
    1     4      8    10

在这种情况下,我希望使用重叠日期的最小值(开始)最大值(结束),因此结果将是:

task   item  start end
   1   1,2,3     0    6
   1       4     8   10

关于如何在sql中解决这个问题有什么想法吗?就像一个挑战,如果不能这样做,我就会去Python。

谢谢

最佳答案

这与我回答的问题类似here ,以及类似的数据“孤岛”问题。但是,您的情况更为复杂,因为“岛屿”的识别需要根据之前的记录来计算。

它最终会看起来像这样:

SET @iEnd = -1; /* init value should be something you don't expect to see */
SET @task = -1; /* init value should be something you don't expect to see */
SET @isNewIsland = 0 /* init value doesn't actually matter */;
SET @i = 0;

SELECT islandNum
   , GROUP_CONCAT(item ORDER BY item) AS items
   , MIN(start) AS iStart
   , MAX(end) AS iEnd
FROM (
    SELECT @isNewIsland := IF(@task <> task OR start > @iEnd, 1, 0)
       , @task := task, item, start, end
       , @i := IF(@isNewIsland = 1, @i + 1, @i) AS islandNum
       , @end := IF(@isNewIsland = 1, end, GREATEST(end, @iEnd))
    FROM ( /* Session(@) variables evaluation can be a bit unpredictable
              the subquery helps guarantee ordering before evaluation */
        SELECT task, item, start, end
        FROM theTable
        ORDER BY task, start, end
    ) AS subQ
) AS subQ 2

有些人不喜欢需要单独的、前面的 SET 语句;为了避免这种需要,请将 ) AS subQ 替换为 ) AS subQ, (SELECT @iEnd := -1, @task := -1, @isNewIsland := 0, @i := 0) AS sInit

关于mysql - 确定日期范围是否包含在 MySQL 中的另一个范围中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41860655/

相关文章:

sql - 同一列的条件更新

mysql - 使用Join执行SQL子查询失败

MySQL 更新性能非常糟糕

mysql - 如何查询 1 个包含 6 列的表,其中 3 列有条件

PHP mysql通过excel导入数据

mysql - 如何在 laravel 中同时使用 whereBetween 和 like 运算符?

php - 静态网页 vs MySql 生成

mysql - 在 SQL 中声明变量的正确方法是什么?

php - 更新字段 1

php - php中while循环内的SQL查询