Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: MySQL запрос c двумя таблицами?
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » MySQL запрос c двумя таблицами?

Страниц (1): [1]
 

1. hivuld - 16 Января, 2019 - 11:50:20 - перейти к сообщению
Всем привет. Допустим, у меня есть таблица с users пользователями, в ней такие поля: id, login, password.
И также есть таблица blacklist, в ней есть такие поля: id, userID, objectID.

Как мне вытащить из таблицы users всех пользователей, у которых userID и objectID в таблице blacklist не равно id пользователя??

Сейчас у меня есть такой запрос:
CODE (htmlphp):
скопировать код в буфер обмена
  1. SELECT * FROM users ORDER BY id DESC LIMIT 0,12
2. andrewkard - 16 Января, 2019 - 16:24:52 - перейти к сообщению
Вот пример
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM match WHERE id NOT IN ( SELECT id FROM email WHERE id IS NOT NULL)

Может есть и получше решение
3. Vladimir Kheifets - 17 Января, 2019 - 08:54:39 - перейти к сообщению
hivuld пишет:
Всем привет. Допустим, у меня есть таблица с users пользователями, в ней такие поля: id, login, password.
И также есть таблица blacklist, в ней есть такие поля: id, userID, objectID.
Как мне вытащить из таблицы users всех пользователей, у которых userID и objectID в таблице blacklist не равно id пользователя??

Добрый день!
Вы хотите вытащить из таблицы users всех пользователей, у которых userID и objectID в таблице blacklist не равно id пользователя таблицы users
т.е. две таблицы не связаны по значениям в полях id. Верно?
м.б. так:
Таблица user
-------------------------------- ------
id login password
1 l1 p1
2 l2 p2
3 l3 p3
4 p4 l4
5 P5 L5

Таблица blacklist
-------------------------------- ------
id userID objectID
1 1 2
2 2 3

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM user WHERE (SELECT count(id) FROM blacklist WHERE userID = user.id OR objectID = user.id )=0


Результат
id login password
4 p4 l4
5 P5 L5

Возможно, что есть решение получше, но это работает.
Советую Вам проверить, не достачно ли связывать таблицы только по user.id и blacklist.userID
Удачи!
4. Мелкий - 17 Января, 2019 - 09:32:11 - перейти к сообщению
Vladimir Kheifets пишет:
(SELECT count(id) FROM blacklist WHERE userID = user.id OR objectID = user.id )=0

Не надо так делать. Нет нужды перебирать и считать всё подходящее, когда заведомо известно, что проверяем существование хотя бы одной строки. Есть куда более подходящие exists/not exists.

andrewkard пишет:
SELECT * FROM match WHERE id NOT IN ( SELECT id FROM email WHERE id IS NOT NULL)

Честно уже не помню насколько внятно это умеет выполнять mysql.
Есть весёлое ограничение из стандарта SQL о том, как именно IN должен обрабатывать ситуацию если в строках подзапроса будет хотя бы один NULL: как NULL всего выражения, независимо от прочих результатов. Из-за этого например в postgresql in хуже эквивалентного exists.

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM user WHERE NOT EXISTS (SELECT 1 FROM blacklist WHERE userID = user.id OR objectID = user.id )

Либо для старых mysql (емнип в 5.6 правили)
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM user LEFT JOIN blacklist ON userID = user.id OR objectID = user.id WHERE blacklist.userID IS NULL
5. Vladimir Kheifets - 17 Января, 2019 - 09:55:06 - перейти к сообщению
Мелкий пишет:
Vladimir Kheifets пишет:
(SELECT count(id) FROM blacklist WHERE userID = user.id OR objectID = user.id )=0

Не надо так делать. Нет нужды перебирать и считать всё подходящее, когда заведомо известно, что проверяем существование хотя бы одной строки. Есть куда более подходящие exists/not exists.

andrewkard пишет:
SELECT * FROM match WHERE id NOT IN ( SELECT id FROM email WHERE id IS NOT NULL)

Честно уже не помню насколько внятно это умеет выполнять mysql.
Есть весёлое ограничение из стандарта SQL о том, как именно IN должен обрабатывать ситуацию если в строках подзапроса будет хотя бы один NULL: как NULL всего выражения, независимо от прочих результатов. Из-за этого например в postgresql in хуже эквивалентного exists.

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM user WHERE NOT EXISTS (SELECT 1 FROM blacklist WHERE userID = user.id OR objectID = user.id )

Либо для старых mysql (емнип в 5.6 правили)
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM user LEFT JOIN blacklist ON userID = user.id OR objectID = user.id WHERE blacklist.userID IS NULL

Согласен, Ваши предложения лучше.
Мне кажется, требуется выбирать только поля из таблицы user, поэтому м.б во второй запрос добавить
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT user.* FROM user LEFT JOIN blacklist ON userID = user.id OR objectID = user.id WHERE blacklist.userID IS NULL
6. Мелкий - 17 Января, 2019 - 10:04:48 - перейти к сообщению
ага, я забыл * поправить для left join. Там по условию бесполезные null будут со второй таблицы всегда.

 

Powered by ExBB FM 1.0 RC1