想象一下一个舞会,我们将男孩排在一侧,女孩排在另一侧。每个男孩都被放入表 A,一次且仅一次。表 B 中的女孩也是如此。
然后,我们希望将 A 中的男孩与 B 中的女孩匹配一次且仅一次,同样,B 中的女孩需要与 A 中的一个且仅有的一个男孩匹配。
A 将有一个 ID 列作为主键,以及一个 b_id 来保存与它们匹配的女孩的 ID,如果尚未匹配则为 NULL。
B 也会为女孩们提供同样的服务。
表格看起来像这样:
table A (boys)
---------
|id|b_id|
---------
| 1|NULL|
| 2|NULL|
| 3|NULL|
| 4|NULL|
| 5|NULL|
| 6|NULL|
---------
table B (girls)
---------
|id|a_id|
---------
| 1|NULL|
| 2|NULL|
| 3|NULL|
| 4|NULL|
| 5|NULL|
| 6|NULL|
---------
什么类型的查询可以将一个且唯一的一个男孩与一个且唯一一个尚未匹配的女孩相匹配?结果看起来像这样:
results
-------------------------
|a.id|a.b_id|b.id|b.a_id|
-------------------------
| 1| NULL | 1| NULL |
| 2| NULL | 2| NULL |
| 3| NULL | 3| NULL |
| 4| NULL | 4| NULL |
| 5| NULL | 5| NULL |
| 6| NULL | 6| NULL |
-------------------------
我可以通过使用具有唯一索引的临时表来获取这些结果,但我正在寻找一个查询来为我提供没有临时表的结果,因为该查询的实际应用程序将针对两侧的数百万行.
最佳答案
SELECT boyUnmatched.id AS aid
, NULL AS b_id --- you really don't need these two
, girlUnmatched.id AS bid
, NULL AS a_id --- columns, do you?
FROM
( SELECT @rownuma := @rownuma+1 AS rank
, id
FROM a
, (SELECT @rownuma :=0) AS dummy
WHERE b_id IS NULL
ORDER BY id
) AS boyUnmatched
JOIN
( SELECT @rownumb := @rownumb+1 AS rank
, id
FROM b
, (SELECT @rownumb :=0) AS dummy
WHERE a_id IS NULL
ORDER BY id
) AS girlUnmatched
ON boyUnmatched.rank = girlUnmatched.rank
关于MYSQL "every row excluded, but only once"加入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7099251/