ВЫБЕРИТЕ все из ТАБЛИЦЫ 1, где какое-то условие НЕ В ТАБЛИЦЕ 2 - PullRequest
0 голосов
/ 12 марта 2020

У меня есть две таблицы:

Таблица 1: члены

mem_id    mem_name
1         Name1
2         Name2
3         Name3
4         Name4

Таблица 2: пролистывания

swp_id    swp_by    swp_to
1         1         3
2         2         3
3         1         2
4         4         1

Здесь член с mem_id 1 пролистанными членами 2 и 3. Таким образом, член id 1 больше не должен видеть участников 2 и 3. Он должен видеть только члена 4, так как он еще не размахивал им. Аналогично, член 2 ударил члена 3, поэтому он больше не должен видеть участника 3, но должен видеть членов 1 и 4.

Мой текущий запрос, который я пробовал:

SELECT * FROM members
LEFT JOIN swipes ON members.mem_id = swipes.swp_to
WHERE mem_id != :mem AND swipes.swp_to IS NULL

Это решает только "половину" " проблема. С помощью этого запроса я могу получить тех пользователей, которые еще не прошли, т. Е. Еще не в swp_to, но я не могу обнаружить пользователя, который проводит. Например, когда пользователь 1 ударил пользователя 2 и 3, этот запрос обнаруживает, что пользователь 2 и 3 был проведен, и, следовательно, больше не показываются, но их не следует показывать только пользователю 1 и все же следует показывать другим пользователям. Здесь они не показываются никому другому.

Я также пытался добавить AND swp_by = mem_id в запрос, но это, кажется, не совсем правильно, поскольку его тоже не работает.

Ответы [ 3 ]

3 голосов
/ 13 марта 2020

Вы можете генерировать все пары членов с (по существу) как cross join. Затем отфильтруйте те, которые были украдены:

select m.mem_id, m2.mem_id
from members m join
     members m2
     on m.mem_id <> m2.mem_id left join
     swipes s
     on s.swp_by = m.mem_id and s.swp_to = m2.mem_id
where s.swp_by is not null;
3 голосов
/ 13 марта 2020

Во-первых, вам нужен (почти) декартово произведение таблицы членов, чтобы получить все возможные комбинации

SELECT m1.mem_id AS m1ID, m2.mem_id AS m2ID
FROM members AS m1 
INNER JOIN members AS m2 ON m1.mem_id != m2.mem_id

, затем вы используете пролистывания для устранения уже спаренных рядов.

SELECT m1.mem_id AS m1ID, m2.mem_id AS m2ID
FROM members AS m1 
INNER JOIN members AS m2 ON m1.mem_id != m2.mem_id
LEFT JOIN swipes AS s ON m1.mem_id = s.swp_by AND m2.mem_id = s.swp_to -- Find corresponding swipes
WHERE s.swp_id IS NULL -- Filter out anything that was swiped
;

ГДЕ условия "логически" применяются после СОЕДИНЕНИЙ.


В качестве альтернативы, если вы хотите только видеть, что члены X еще не разобрались ....

SELECT m.*
FROM members AS m
WHERE m.mem_id <> X
  AND m.mem_id NOT IN (SELECT swp_to FROM swipes WHERE swp_by = X)
;

или

SELECT m.*
FROM members AS m
LEFT JOIN swipes AS s ON m.mem_id = s.swp_to AND s.swp_by = X
WHERE m.mem_id <> X AND s.swp_id IS NULL
;

При большом столе, хотя первый вариант даст вам все потенциальные совпадения, он будет «взрываться» с результатами; примерно M * (M-1) - S, где M = количество членов и S = ​​количество ударов. Эта версия будет просто получать потенциальные совпадения для каждого участника, но будет гораздо менее ресурсоемкой. Примечание: последний из этих двух с большей вероятностью сможет воспользоваться индексом на swipes(swp_by, swp_to).

1 голос
/ 13 марта 2020

Вы можете сделать это с помощью NOT EXISTS:

SELECT m.* FROM members m
WHERE m.mem_id <> :mem
AND NOT EXISTS (
  SELECT 1   
  FROM swipes
  WHERE swp_by = :mem AND swp_to = m.mem_id  
);

См. Демоверсию .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...