mysql - 如何获得连接的对立面?

标签 mysql join left-join

我正在尝试获取一个表中不存在的行,其中一个名为 schedules (match_week, player_home_id, player_away_id) 的表与另一个名为 match (match_week, Winner_id, Defeated_id) 的表相连。球员们查看他们的日程安排并进行比赛。我正在尝试获取匹配表中不存在的预定匹配列表。匹配表中的 ID 可以在 Winner_id 或 Defeated_id 列中。

我查看了许多 Stack Exchange 示例,但大多数使用“IS NULL”并且我没有空值。我使用了一个 Join ,它确实提供了所玩比赛的输出。我想要还没有打过的比赛。

CSV - wp_schedule_test

+----+------------+--------------+--------------+-----------------+-----------------+
| ID | match_week | home_player1 | away_player1 | player1_home_id | player1_away_id |
+----+------------+--------------+--------------+-----------------+-----------------+
|  1 | WEEK 1     | James Rives  | Dale Hemme   |             164 |             169 |
|  2 | WEEK 1     | John Head    | David Foster |              81 |             175 |
|  3 | WEEK 1     | John Dalton  | Eric Simmons |              82 |              23 |
|  4 | WEEK 2     | John Head    | James Rives  |              81 |             164 |
|  5 | WEEK 2     | Dale Hemme   | John Dalton  |             169 |              82 |
|  6 | WEEK 2     | David Foster | Eric Simmons |             175 |              23 |
|  7 | WEEK 3     | John Dalton  | James Rives  |              82 |             164 |
|  8 | WEEK 3     | John Head    | Eric Simmons |              81 |              23 |
|  9 | WEEK 3     | Dale Hemme   | David Foster |             169 |             175 |
| 10 | WEEK 4     | Eric Simmons | James Rives  |              23 |             164 |
| 11 | WEEK 4     | David Foster | John Dalton  |             175 |              82 |
| 12 | WEEK 4     | Dale Hemme   | John Head    |             169 |              81 |
+----+------------+--------------+--------------+-----------------+-----------------+

CSV - wp_match_scores_test

+----+------------+------------+------------+
| ID | match_week | player1_id | player2_id |
+----+------------+------------+------------+
|  5 | WEEK 1     |         82 |         23 |
| 20 | WEEK 1     |        164 |        169 |
| 21 | WEEK 2     |        164 |         81 |
| 25 | WEEK 2     |         82 |        169 |
| 61 | WEEK 3     |        175 |        169 |
| 62 | WEEK 4     |        175 |         82 |
| 69 | WEEK 2     |        175 |         23 |
| 85 | WEEK 3     |        164 |         82 |
| 86 | WEEK 4     |        164 |         23 |
+----+------------+------------+------------+

mysql 查询的输出是已经进行过的比赛。我想弄清楚如何从表 Schedule 中列出尚未播放的比赛。

CSV - MySQL 输出

+------------+------------+------------+
| match_week | player1_id | player2_id |
+------------+------------+------------+
| WEEK 1     |        164 |        169 |
| WEEK 1     |         82 |         23 |
| WEEK 2     |        164 |         81 |
| WEEK 2     |         82 |        169 |
| WEEK 2     |        175 |         23 |
| WEEK 3     |        175 |        169 |
| WEEK 3     |        164 |         82 |
| WEEK 4     |        175 |         82 |
| WEEK 4     |        164 |         23 |
+------------+------------+------------+

数据库

select DISTINCT ms.match_week, ms.player1_id , ms.player2_id FROM 
wp_match_scores_test ms
JOIN wp_schedules_test s 
ON (s.player1_home_id = ms.player1_id or s.player1_away_id = 
ms.player2_id)
Order by ms.match_week

预期的输出是:

CSV - 期望的输出

+------------+----------------+----------------+
| match_week | player_home_id | player_away_id |
+------------+----------------+----------------+
| WEEK 1     |             81 |            175 |
| WEEK 3     |             81 |             23 |
| WEEK 4     |            169 |             81 |
+------------+----------------+----------------+

我想使用的添加代码是

SELECT s.*
FROM wp_schedules_test s
WHERE NOT EXISTS
(select DISTINCT ms.match_week, ms.player1_id , ms.player2_id FROM 
wp_match_scores_test ms
JOIN wp_schedules_test s 
ON (s.player1_home_id = ms.player1_id or s.player1_away_id = 
ms.player2_id)
Order by ms.match_week)

不幸的是,输出结果为“No Rows”

最佳答案

您可以使用 LEFT JOIN 来获得所需的结果,在匹配的玩家 ID 上连接两个表(注意 wp_match_scores_test 中的玩家 ID 值可以对应于 player1_home_idwp_schedules_test 中的 player1_away_id)。如果没有比赛,结果表将具有 wp_match_scores_test 表值中的 NULL 值,您可以使用它来选择尚未进行的比赛:

SELECT sch.*
FROM wp_schedule_test sch
LEFT JOIN wp_match_scores_test ms 
       ON (ms.player1_id = sch.player1_home_id
        OR ms.player2_id = sch.player1_home_id)
      AND (ms.player1_id = sch.player1_away_id
        OR ms.player2_id = sch.player1_away_id)
WHERE ms.ID IS NULL

输出:

ID  match_week  home_player1    away_player1    player1_home_id player1_away_id
2   Week 1      John Head       David Foster    81              175
8   Week 3      John Head       Eric Simmons    81              23
12  Week 4      Dale Hemme      John Head       169             81

请注意,您还可以使用 NOT EXISTS 查询,使用与我在 JOIN 中使用的相同条件:

SELECT sch.*
FROM wp_schedule_test sch
WHERE NOT EXISTS (SELECT * 
                  FROM wp_match_scores_test ms 
                  WHERE (ms.player1_id = sch.player1_home_id
                      OR ms.player2_id = sch.player1_home_id)
                    AND (ms.player1_id = sch.player1_away_id
                      OR ms.player2_id = sch.player1_away_id))

这个查询的输出是一样的。请注意,必须针对结果集中的每一行评估 WHERE 子句中的条件,这通常会使此查询的效率低于等效的 LEFT JOIN

Demo on dbfiddle

关于mysql - 如何获得连接的对立面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57702795/

相关文章:

mysql - 左连接更新的行为

php - MySQL :You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''

php - 帮助数组列表 - PHP MYSQL

mysql - 依靠工作历史日志

ms-access - 连接表并显示表一张表上的所有行,但当我在其中使用条件时不显示

MySQL - 计数没有返回我正在寻找的值

mysql - 将数据链接到另一个表中的唯一索引

MySQL:如何将参数传递给触发器

MySQL 左连接和排除值

sql-server - 在 SQL 中连接 2 个表变量