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

Sim*_*mon 8 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
Run Code Online (Sandbox Code Playgroud)

此数据使用DateTime字段按时间顺序排序.我想将这些记录'对'显示为1行,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

有几点需要注意:如果没有Type1启动,则在结果表的Type1Km字段中显示NULL.同样,如果没有Type2结束,则在记录的Type2Km字段中显示NULL.

我怎么能这样做?

Wis*_*guy 4

不幸的是,MySQL 缺少FULL OUTER JOIN,因此您必须将UNION两套放在一起。

这将为您提供存在的情况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
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

UNION把它们放在一起,你就得到了想要的结果:

(
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

) UNION ALL (

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)
)

ORDER BY `StartTime`
Run Code Online (Sandbox Code Playgroud)

更新

在我之前的查询中,我忘记在一开始就考虑到有“类型 2”记录。已更新以说明这一点。这是我得到的结果:

表中数据times

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
Run Code Online (Sandbox Code Playgroud)

查询结果:

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)
Run Code Online (Sandbox Code Playgroud)