我有一张表看起来像这样
Board
我希望我的结果看起来像
start_time end_time
2016-10-26 08:45:00 2016-10-27 09:45:00
2016-10-26 09:45:00 2016-10-26 10:45:00
2016-10-27 07:45:00 2016-10-27 11:45:00
请帮助我
编辑
start_time end_time
2016-10-26 08:45:00 2016-10-26 10:45:00
2016-10-27 07:45:00 2016-10-27 11:45:00
但是当开始时间和结束时间没有在同一天发生时,它会一直显示错误的结果。
答案 0 :(得分:0)
SELECT
MIN(startDate.start_time) AS start_time,
MAX(endDate.end_time) AS end_time
FROM
dates AS startDate
LEFT JOIN dates AS endDate
ON DATE_FORMAT(startDate.start_time, '%Y-%m-%d') = DATE_FORMAT(endDate.end_time, '%Y-%m-%d')
GROUP BY
DATE_FORMAT(startDate.start_time, '%Y-%m-%d');
因为start_time和end_time总是在同一天发生,你必须加入end_times然后查找当天的最新时间。
这个可能会在index
上使用end_time
。如果列上有index
,您应该尝试查找它。
SELECT
MIN(startDate.start_time) AS start_time,
MAX(endDate.end_time) AS end_time
FROM
dates AS startDate
LEFT JOIN dates AS endDate
ON endDate.end_time BETWEEN DATE_FORMAT(startDate.start_time, '%Y-%m-%d 00:00:00') AND DATE_FORMAT(startDate.start_time, '%Y-%m-%d 23:59:59')
GROUP BY
DATE_FORMAT(startDate.start_time, '%Y-%m-%d');
我将稍微更改您的示例数据,以便您了解我选择使用join
获取end_time
的原因。我们将专注于 2016-10-26 的日期。
结果将与您的示例相同:
start_time end_time
2016-10-26 08:45:00 2016-10-26 10:45:00
我们有以下数据。如您所见,结果中的值位于原始数据的不同行中。第一行中start_time
的值,第二行中end_time
的值。
start_time end_time
2016-10-26 08:45:00 2016-10-27 09:45:00
2016-10-27 09:45:00 2016-10-26 10:45:00
2016-10-27 07:45:00 2016-10-27 11:45:00
2016-10-26 10:30:00 2016-10-26 10:40:00
第一步 - 准备数据
第一步是将匹配的end_time与start_times匹配。因此,对于我们的数据集,end_times的日期为2016-10-26。
为此,我们join
格式化datetime列,以便删除时间。我们转向" 2016-10-26 10:40:00"进入" 2016-10-26"。
SELECT
startDate.start_time AS start_time,
endDate.end_time AS end_time
FROM
dates AS startDate
LEFT JOIN dates AS endDate
ON DATE_FORMAT(startDate.start_time, '%Y-%m-%d') = DATE_FORMAT(endDate.end_time, '%Y-%m-%d')
这为我们提供了一些在start_time和end_time列上具有相同日期的行。它是start_time和end_time的笛卡尔积,限于同一天。
+---------------------+---------------------+
| start_time | end_time |
+---------------------+---------------------+
| 2016-10-26 08:45:00 | 2016-10-26 10:45:00 |
| 2016-10-26 08:45:00 | 2016-10-26 10:40:00 |
| 2016-10-27 09:45:00 | 2016-10-27 09:45:00 |
| 2016-10-27 09:45:00 | 2016-10-27 11:45:00 |
| 2016-10-27 07:45:00 | 2016-10-27 09:45:00 |
| 2016-10-27 07:45:00 | 2016-10-27 11:45:00 |
| 2016-10-26 10:30:00 | 2016-10-26 10:45:00 |
| 2016-10-26 10:30:00 | 2016-10-26 10:40:00 |
+---------------------+---------------------+
第二步 - 按天分组
现在我们可以简单地对它进行分组,我们再次只想使用日期时间字段的日期,因此我们对其进行格式化以便时间被删除。
SELECT
startDate.start_time AS start_time,
endDate.end_time AS end_time
FROM
dates AS startDate
LEFT JOIN dates AS endDate
ON DATE_FORMAT(startDate.start_time, '%Y-%m-%d') = DATE_FORMAT(endDate.end_time, '%Y-%m-%d')
GROUP BY
DATE_FORMAT(startDate.start_time, '%Y-%m-%d')
这将给我们一些随机的结果集*,它按天分组。
如果数据的顺序正确,它甚至可能看起来是正确的结果......危险。您可以在小提琴中看到它,2016-10-26的数据是为了显示正确的'结果,2016-10-27的数据不是。
此查询也可能会给您一个错误,因为您选择的是非聚合列和非聚类列 - 取决于您的mysql版本和配置
最后一步 - 获取正确的数据
为了获得正确的结果,我们现在使用聚合函数MIN()
和MAX()
。
SELECT
MIN(startDate.start_time) AS start_time,
MAX(endDate.end_time) AS end_time
FROM
dates AS startDate
LEFT JOIN dates AS endDate
ON DATE_FORMAT(startDate.start_time, '%Y-%m-%d') = DATE_FORMAT(endDate.end_time, '%Y-%m-%d')
GROUP BY
DATE_FORMAT(startDate.start_time, '%Y-%m-%d')
+---------------------+---------------------+
| start_time | end_time |
+---------------------+---------------------+
| 2016-10-26 08:45:00 | 2016-10-26 10:45:00 |
| 2016-10-27 07:45:00 | 2016-10-27 11:45:00 |
+---------------------+---------------------+