mysql - 从可能对应日期的 2 个表中选择
问题描述
我正在为我的 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 分钟或同一小时内)。例如。如果列 weight 有一个 2019-01-01 00:00:00 的条目,并且 table height 在 2019-01-01 00:04:00 有一个高度条目,它们会出现在同一行中。
解决方案
UNION
您可以使用 a从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
输出(来自我的演示,我修改了您的时间以允许在一小时内匹配):
user_id created_on weight height
2 19-01-01 01:00:00 80 180
2 19-01-02 00:00:00 181
2 19-01-04 04:00:00 81
2 19-01-07 06:00:00 84 184
推荐阅读
- asp.net - 使用 authorization_code 授权类型请求令牌
- python - AttributeError Django 休息框架
- python - Colab 中的 Tensorboard:当前数据集没有处于活动状态的仪表板
- scala - 如何创建 [(Row, Row)] 的数据集
- sql - 如何使用 JOIN ON 连接两个表
- typescript - 仅允许来自枚举的值但不要求枚举中的每个值都存在的类型
- sql - 如何将行转换为具有指定列名的列?
- swift - 图片未出现在聊天中 - MessageKit
- javascript - 当我使用自定义挂钩时,如何在 useEffect 中的操作后设置默认值
- javascript - Javascript 对象箭头函数和 this