MySQL Left Join Right Join union returns 数据不正确
MySQL Left Join Right Join union returns incorrect data
我和我的同学一直在 运行 疯狂地尝试让这个查询正常工作。
目标: Return 由两个 table 组成的单个 table 通过左连接完全连接然后正确加入。会有空值。这个 table 的目的是用左 Y 轴上的速度和右 Y 轴上的重量来绘制速度和重量的图表,以便跟踪重量与速度的一致性。某些值将具有共享日期。
假设:
- 一个玩家不能在一天内多次记录他们的体重。
- 一个玩家不能在一天内多次输入冲刺速度。
- 任何日期都不能独立于冲刺值或体重而存在。他们必须至少有一个与之关联的值。
问题: 有几行返回了本应为 NULL 的值,我们不知道这些数据的来源。
当前错误查询:
SELECT weight.username, weight.weight, metric.speedOrDistance, weighInDate
FROM playerweight as weight LEFT JOIN sprint AS metric ON
weight.weighInDate = metric.workoutDate
WHERE weight.username = 'testuser'
UNION
SELECT metric.username, weight.weight,
metric.speedOrDistance, workoutDate
FROM playerweight as weight RIGHT
JOIN sprint AS metric ON weight.weighInDate = metric.workoutDate
WHERE metric.username = 'testuser'
ORDER BY weighInDate;
示例数据:
冲刺Table
+----------+-------------+-----------------+
| username | workoutDate | speedOrDistance |
+----------+-------------+-----------------+
| jdoe | 2016-10-10 | 2.00 |
| jdoe | 2016-10-17 | 3.50 |
| jdoe | 2016-10-24 | 3.00 |
| jdoe | 2016-11-01 | 5.00 |
| jdoe | 2016-11-10 | 4.00 |
| foo | 2016-11-03 | 2.50 |
| foo | 2016-11-14 | 5.00 |
| foo | 2016-11-16 | 4.00 |
| foo | 2016-11-18 | 3.00 |
| testuser | 2016-10-11 | 3.40 |
| testuser | 2016-10-17 | 3.40 |
| testuser | 2016-11-13 | 1.50 |
| testuser | 2016-11-15 | 2.00 |
| testuser | 2016-11-17 | 4.00 |
+----------+-------------+-----------------+
球员体重
+----------+-------------+--------+
| username | weighInDate | weight |
+----------+-------------+--------+
| jdoe | 2016-10-10 | 160 |
| jdoe | 2016-10-17 | 160 |
| jdoe | 2016-10-24 | 170 |
| jdoe | 2016-11-01 | 180 |
| jdoe | 2016-11-08 | 180 |
| jdoe | 2016-11-09 | 200 |
| jdoe | 2016-11-11 | 178 |
| jdoe | 2016-11-22 | 195 |
| foo | 2016-11-01 | 190 |
| foo | 2016-11-10 | 185 |
| foo | 2016-11-14 | 175 |
| foo | 2016-11-18 | 180 |
| bar | 2011-01-16 | 170 |
| bar | 2011-07-16 | 177 |
| bar | 2011-09-16 | 169 |
| testuser | 2016-11-04 | 150 |
| testuser | 2016-11-08 | 200 |
| testuser | 2016-11-11 | 195 |
| testuser | 2016-11-14 | 175 |
| testuser | 2016-11-17 | 180 |
+----------+-------------+--------+
不正确的结果Table
+----------+--------+-----------------+-------------+
| username | weight | speedOrDistance | weighInDate |
+----------+--------+-----------------+-------------+
| testuser | NULL | 3.4 | 2016-10-11 |
| testuser | 160 | 3.4 | 2016-10-17 | -- ERROR ROW, weight should not have a value
| testuser | 150 | NULL | 2016-11-04 |
| testuser | 200 | NULL | 2016-11-08 |
| testuser | 195 | NULL | 2016-11-11 |
| testuser | NULL | 1.5 | 2016-11-13 |
| testuser | 175 | 5 | 2016-11-14 | -- ERROR ROW, speedOrDistance should not have a value
| testuser | NULL | 2 | 2016-11-15 |
| testuser | 180 | 4 | 2016-11-17 |
+----------+--------+-----------------+-------------+
理想结果Table
+----------+--------+-----------------+-------------+
| username | weight | speedOrDistance | weighInDate |
+----------+--------+-----------------+-------------+
| testuser | NULL | 3.4 | 2016-10-11 |
| testuser | NULL | 3.4 | 2016-10-17 |
| testuser | 150 | NULL | 2016-11-04 |
| testuser | 200 | NULL | 2016-11-08 |
| testuser | 195 | NULL | 2016-11-11 |
| testuser | NULL | 1.5 | 2016-11-13 |
| testuser | 175 | NULL | 2016-11-14 |
| testuser | NULL | 2 | 2016-11-15 |
| testuser | 180 | 4 | 2016-11-17 |
+----------+--------+-----------------+-------------+
非常感谢你们能提供的任何帮助。我们不知道为什么这不起作用。
谢谢!!!
您在 workoutDate = weighInDate
上进行联接。这为您提供了不相关行的组合,这些行保留在结果集中,即使具有不相关的用户名也是如此。
要解决此问题,您必须在日期和用户名上加入,例如
LEFT JOIN sprint AS metric ON weight.weighInDate = metric.workoutDate
and weight.username = metric.username
同样在右侧加入,当然。
已添加到答案中,因为它有助于说明问题的原因。 @OlafDietsche 有正确的解决方案。我只是想让你看看实际的错误数据是从哪里来的。
向您展示加入此记录的问题:
| testuser | 2016-10-17 | 3.40
正在加入此记录
| jdoe | 2016-10-17 | 160 |
因为您是在日期才加入的。
我和我的同学一直在 运行 疯狂地尝试让这个查询正常工作。
目标: Return 由两个 table 组成的单个 table 通过左连接完全连接然后正确加入。会有空值。这个 table 的目的是用左 Y 轴上的速度和右 Y 轴上的重量来绘制速度和重量的图表,以便跟踪重量与速度的一致性。某些值将具有共享日期。
假设:
- 一个玩家不能在一天内多次记录他们的体重。
- 一个玩家不能在一天内多次输入冲刺速度。
- 任何日期都不能独立于冲刺值或体重而存在。他们必须至少有一个与之关联的值。
问题: 有几行返回了本应为 NULL 的值,我们不知道这些数据的来源。
当前错误查询:
SELECT weight.username, weight.weight, metric.speedOrDistance, weighInDate
FROM playerweight as weight LEFT JOIN sprint AS metric ON
weight.weighInDate = metric.workoutDate
WHERE weight.username = 'testuser'
UNION
SELECT metric.username, weight.weight,
metric.speedOrDistance, workoutDate
FROM playerweight as weight RIGHT
JOIN sprint AS metric ON weight.weighInDate = metric.workoutDate
WHERE metric.username = 'testuser'
ORDER BY weighInDate;
示例数据:
冲刺Table
+----------+-------------+-----------------+
| username | workoutDate | speedOrDistance |
+----------+-------------+-----------------+
| jdoe | 2016-10-10 | 2.00 |
| jdoe | 2016-10-17 | 3.50 |
| jdoe | 2016-10-24 | 3.00 |
| jdoe | 2016-11-01 | 5.00 |
| jdoe | 2016-11-10 | 4.00 |
| foo | 2016-11-03 | 2.50 |
| foo | 2016-11-14 | 5.00 |
| foo | 2016-11-16 | 4.00 |
| foo | 2016-11-18 | 3.00 |
| testuser | 2016-10-11 | 3.40 |
| testuser | 2016-10-17 | 3.40 |
| testuser | 2016-11-13 | 1.50 |
| testuser | 2016-11-15 | 2.00 |
| testuser | 2016-11-17 | 4.00 |
+----------+-------------+-----------------+
球员体重
+----------+-------------+--------+
| username | weighInDate | weight |
+----------+-------------+--------+
| jdoe | 2016-10-10 | 160 |
| jdoe | 2016-10-17 | 160 |
| jdoe | 2016-10-24 | 170 |
| jdoe | 2016-11-01 | 180 |
| jdoe | 2016-11-08 | 180 |
| jdoe | 2016-11-09 | 200 |
| jdoe | 2016-11-11 | 178 |
| jdoe | 2016-11-22 | 195 |
| foo | 2016-11-01 | 190 |
| foo | 2016-11-10 | 185 |
| foo | 2016-11-14 | 175 |
| foo | 2016-11-18 | 180 |
| bar | 2011-01-16 | 170 |
| bar | 2011-07-16 | 177 |
| bar | 2011-09-16 | 169 |
| testuser | 2016-11-04 | 150 |
| testuser | 2016-11-08 | 200 |
| testuser | 2016-11-11 | 195 |
| testuser | 2016-11-14 | 175 |
| testuser | 2016-11-17 | 180 |
+----------+-------------+--------+
不正确的结果Table
+----------+--------+-----------------+-------------+
| username | weight | speedOrDistance | weighInDate |
+----------+--------+-----------------+-------------+
| testuser | NULL | 3.4 | 2016-10-11 |
| testuser | 160 | 3.4 | 2016-10-17 | -- ERROR ROW, weight should not have a value
| testuser | 150 | NULL | 2016-11-04 |
| testuser | 200 | NULL | 2016-11-08 |
| testuser | 195 | NULL | 2016-11-11 |
| testuser | NULL | 1.5 | 2016-11-13 |
| testuser | 175 | 5 | 2016-11-14 | -- ERROR ROW, speedOrDistance should not have a value
| testuser | NULL | 2 | 2016-11-15 |
| testuser | 180 | 4 | 2016-11-17 |
+----------+--------+-----------------+-------------+
理想结果Table
+----------+--------+-----------------+-------------+
| username | weight | speedOrDistance | weighInDate |
+----------+--------+-----------------+-------------+
| testuser | NULL | 3.4 | 2016-10-11 |
| testuser | NULL | 3.4 | 2016-10-17 |
| testuser | 150 | NULL | 2016-11-04 |
| testuser | 200 | NULL | 2016-11-08 |
| testuser | 195 | NULL | 2016-11-11 |
| testuser | NULL | 1.5 | 2016-11-13 |
| testuser | 175 | NULL | 2016-11-14 |
| testuser | NULL | 2 | 2016-11-15 |
| testuser | 180 | 4 | 2016-11-17 |
+----------+--------+-----------------+-------------+
非常感谢你们能提供的任何帮助。我们不知道为什么这不起作用。
谢谢!!!
您在 workoutDate = weighInDate
上进行联接。这为您提供了不相关行的组合,这些行保留在结果集中,即使具有不相关的用户名也是如此。
要解决此问题,您必须在日期和用户名上加入,例如
LEFT JOIN sprint AS metric ON weight.weighInDate = metric.workoutDate
and weight.username = metric.username
同样在右侧加入,当然。
已添加到答案中,因为它有助于说明问题的原因。 @OlafDietsche 有正确的解决方案。我只是想让你看看实际的错误数据是从哪里来的。
向您展示加入此记录的问题:
| testuser | 2016-10-17 | 3.40
正在加入此记录
| jdoe | 2016-10-17 | 160 |
因为您是在日期才加入的。