MySQL Left Join Right Join union返回不正确的数据

时间:2016-11-18 18:02:38

标签: mysql sql left-join union right-join

我的同学和我一直在猖獗,试图让这个查询正常工作。

目标:返回一个包含两个表的表,这两个表通过左连接和右连接完全连接。将有空值。此表的目的是在左侧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;

示例数据:

冲刺表

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

playerWeight

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

结果表不正确

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

理想结果表

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

你们提供的任何帮助都将不胜感激。我们不知道为什么这不起作用。

谢谢!!!

1 个答案:

答案 0 :(得分:3)

您在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 |

因为你只参加了约会。