我正在为我的mysql数据库寻找正确的查询,该数据库具有2个单独的长度和重量表。 我希望将结果作为1列3列查询返回:日期时间,长度和重量。 该查询还应允许指定用户。 例如:
桌子高度:
id user_id created_on height
1 2 2019-01-01 00:00:01 180
2 2 2019-01-02 00:00:01 181
3 3 2019-01-03 00:00:01 182
4 3 2019-01-04 00:00:01 183
5 2 2019-01-07 00:00:01 184
表重:
id user_id created_on weight
1 2 2019-01-01 00:00:01 80
2 2 2019-01-04 00:00:01 81
3 3 2019-01-05 00:00:01 82
4 3 2019-01-06 00:00:01 83
5 2 2019-01-07 00:00:01 84
我希望通过一个查询获得以下结果:
user_id created_on weight height
2 2019-01-01 00:00:01 80 180
2 2019-01-02 00:00:01 null 181
2 2019-01-04 00:00:01 81 null
2 2019-01-07 00:00:01 84 184
我曾尝试使用JOIN语句,但未能获得所需的结果。 此连接语句
SELECT w.* , h.* FROM weight w
JOIN height h
ON w.created_on=h.created_on
AND w.user_id=h.user_id AND user_id=2
将仅返回同时包含user_id和created_on的身高和体重项目的那些结果 完全外部联接可以解决问题,但是mysql不支持。 以下查询似乎正在返回所需的结果,但是它非常慢:
SELECT r.* FROM
(SELECT w.user_id as w_user, w.created_on as weightdate, w.value as weight, h.created_on as heightdate ,h.user_id as h_user, h.value as height FROM weight w
LEFT JOIN height h ON w.user_id = h.user_id
AND w.created_on=h.created_on
UNION
SELECT w.user_id as w_user, w.created_on as weightdate, w.value as weight, h.created_on as heightdate ,h.user_id as h_user, h.value as height FROM weight w
RIGHT JOIN height h ON w.user_id = h.user_id
AND w.created_on=h.created_on ) r
WHERE h_user=2 OR w_user =2
如果2个表具有大约3000个条目,则查询将花费3秒钟以上的时间。 有没有办法加快速度,可能使用其他方法?
要获得额外的奖励积分:是否可以在两个created_on日期时间之间留出一点时间差异? (例如10分钟或同一小时内)。例如。如果列权重在2019-01-01 00:00:00处有一个条目,而表格高度在2019-01-01 00:04:00处有一个高度的条目,则它们出现在同一行。
答案 0 :(得分:1)
您可以使用@Autowire
从UNION
和heights
表中选择所有不同的日期,而不是使用日历表选择感兴趣的日期。要处理彼此在一小时内的匹配时间,可以使用weights
比较时间并将TIMESTAMPDIFF
时间截断为该小时。由于这可能会创建重复的条目,因此我们在查询中添加了created_on
限定词:
DISTINCT
输出(从我的演示中,我修改了您的时间以允许在一小时内进行匹配):
SELECT DISTINCT COALESCE(h.user_id, w.user_id) AS user_id,
DATE_FORMAT(COALESCE(h.created_on, w.created_on), '%y-%m-%d %H:00:00') AS created_on,
w.weight,
h.height
FROM (SELECT created_on FROM heights
UNION
SELECT created_on FROM weights) d
LEFT JOIN heights h ON ABS(TIMESTAMPDIFF(HOUR, h.created_on, d.created_on)) = 0 AND h.user_id = 2
LEFT JOIN weights w ON ABS(TIMESTAMPDIFF(HOUR, w.created_on, d.created_on)) = 0 AND w.user_id = 2
WHERE h.user_id IS NOT NULL OR w.user_id IS NOT NULL
ORDER BY created_on
答案 1 :(得分:0)
这可能最好使用日历表来处理,该表包含查询的所有感兴趣的日期。我们可以从日历表开始查询,然后左移到身高和体重表:
SELECT
COALESCE(h.user_id, w.user_id) AS user_id,
d.dt AS created_on,
w.weight,
h.height
FROM
(
SELECT '2019-01-01 00:00:01' AS dt UNION ALL
SELECT '2019-01-02 00:00:01' UNION ALL
SELECT '2019-01-03 00:00:01' UNION ALL
SELECT '2019-01-04 00:00:01' UNION ALL
SELECT '2019-01-05 00:00:01' UNION ALL
SELECT '2019-01-06 00:00:01' UNION ALL
SELECT '2019-01-07 00:00:01'
) d
LEFT JOIN heights h
ON d.dt = h.created_on AND h.user_id = 2
LEFT JOIN weights w
ON d.dt = w.created_on AND w.user_id = 2
WHERE
h.user_id IS NOT NULL OR w.user_id IS NOT NULL
ORDER BY
d.dt;