MYSQL "каждая строка исключена, но только один раз" присоединиться - PullRequest
2 голосов
/ 18 августа 2011

Представьте себе танцевальную вечеринку, где мы выстраиваем в ряд мальчиков с одной стороны и девочек с другой.Каждый мальчик помещается в таблицу А один раз и только один раз.Аналогично для девочек в таблице B.

Затем мы хотим сопоставить мальчиков в A один раз и только один раз с девушкой в ​​B, и аналогичным образом девушки в B должны соответствовать одному и только одному мальчику вA.

A будет иметь столбец идентификатора в качестве первичного ключа и b_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 |
-------------------------

Я могу получить эти результаты, используя временную таблицу с уникальными индексами, но я ищу запрос, который даст мне результаты без временной таблицы в качестве реальнойприменение этого запроса идет против миллионов строк с обеих сторон.

1 Ответ

3 голосов
/ 18 августа 2011
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...