MySQL-在一条记录中显示记录对

MySQL-在一条记录中显示记录对,mysql,sql,join,Mysql,Sql,Join,我在一个表中有以下数据: Time, Type, Kilometers 12:00, 1, 0.1 12:30, 2, 0.2 14:00, 1, 0.4 15:00, 2, 1.0 16:00, 1, 1.2 16:30, 2, 1.5 16:45, 1, 2.0 此数据使用DateTime字段按时间顺序排序。我想将这些记录“对”显示为一行,如下所示: StartTime, Type1Km, Type2Km 12:00, 0.1, 0.2 14:00, 0.4, 1.0 16:00, 1.2

我在一个表中有以下数据:

Time, Type, Kilometers
12:00, 1, 0.1
12:30, 2, 0.2
14:00, 1, 0.4
15:00, 2, 1.0
16:00, 1, 1.2
16:30, 2, 1.5
16:45, 1, 2.0
此数据使用DateTime字段按时间顺序排序。我想将这些记录“对”显示为一行,如下所示:

StartTime, Type1Km, Type2Km
12:00, 0.1, 0.2
14:00, 0.4, 1.0
16:00, 1.2, 1.5
16:45, 2.0, NULL
有两个警告:如果没有要启动的Type1,那么在结果表的Type1Km字段中显示NULL。同样,如果没有Type2结尾,则在记录的Type2Km字段中显示NULL


我怎么能做到这一点呢?

不幸的是,MySQL缺少一个
完整的外部连接
,因此您必须
将两个集合合并在一起

这将为您提供
Type1Km
存在的情况,无论
Type2Km
是否存在

SELECT
    t1.`Time` as StartTime,
    t1.`Kilometers` as Type1Km,
    t2.`Kilometers` as Type2Km
FROM `times` t1
LEFT JOIN `times` t2 ON t2.`Type` = 2
                    AND t2.`Time` = (SELECT `Time` FROM `times`
                                     WHERE `Time` > t1.`Time`
                                     ORDER BY `Time` LIMIT 1)
WHERE t1.`Type` = 1
现在我们需要
Type1Km
不存在的情况

SELECT
    t2.`Time` as StartTime,
    NULL as Type1Km,
    t2.`Kilometers` as Type2Km
FROM `times` t2
LEFT JOIN `times` t1 ON t1.`Time` = (SELECT `Time` FROM `times`
                                     WHERE `Time` < t2.`Time`
                                     ORDER BY `Time` DESC LIMIT 1)
WHERE t2.`Type` = 2
  AND (t1.`Type` = 2 OR t1.`Type` IS NULL)

更新

在我之前的查询中,我忘记了在一开始就有一个“Type2”记录。对此进行了更新。以下是我得到的结果:

时间
表中的数据:

+----------+------+------------+
|时间|类型|公里|
+----------+------+------------+
| 11:00:00 |    2 |        0.1 |
| 12:00:00 |    1 |        0.1 |
| 12:30:00 |    2 |        0.2 |
| 14:00:00 |    1 |        0.4 |
| 14:30:00 |    1 |        0.8 |
| 15:00:00 |    2 |        1.0 |
| 15:30:00 |    2 |        0.2 |
| 16:00:00 |    1 |        1.2 |
| 16:30:00 |    2 |        1.5 |
| 16:45:00 |    1 |        2.0 |
+----------+------+------------+
查询结果:

+-----------+---------+---------+
|起始时间|类型1km |类型2km|
+-----------+---------+---------+
|11:00:00 |空| 0.1|
| 12:00:00  |     0.1 |     0.2 |
|14:00:00 | 0.4 |零|
| 14:30:00  |     0.8 |     1.0 |
|15:30:00 |零| 0.2|
| 16:00:00  |     1.2 |     1.5 |
|16:45:00 | 2.0 |空|
+-----------+---------+---------+

如果可以,请将表结构更改为type1km和type2km,然后在添加kms时更新,或者在选择kms时进行汇总。

这可能有效

select 
max(Time), 
substring_index(group_concat(if(type=2,null,Kilometers) order by type),',',1),
substring_index(group_concat(if(type=1,null,Kilometers) order by type desc),',',1) 
from your_table 
group by date_format(Time, '%H');
我假设按小时分组,也不值得你举例,结果不准确

更好地解释这个有趣的查询的作用

group_concat(if(type=2,null,Kilometers) order by type
-- this is ensure the Kilometers must NOT from type=2

group_concat(if(type=1,null,Kilometers) order by type desc
-- this is ensure the Kilometers must NOT from type=1

棘手的部分是,你要将一段时间的类型1与下一段时间的类型2结合起来。如果“一行”中有2个类型1,那么类型2km应该为空,对吗?@MPelletier-正确(这不太可能发生,但如果解决方案考虑到这一点,这将是有益的)如果此表有一个自动递增列链接X到X+1进行差分测试,我将更容易处理。。。有没有一个是上面没有提到的?进一步说@DRapp问:这可靠吗?时间会按顺序插入吗?@DRapp,有,但是不能保证(也可能不会)type2=X+1
group_concat(if(type=2,null,Kilometers) order by type
-- this is ensure the Kilometers must NOT from type=2

group_concat(if(type=1,null,Kilometers) order by type desc
-- this is ensure the Kilometers must NOT from type=1