LINUX.ORG.RU

[MySQL, LEFT JOIN] Запутался


0

1

Есть запрос:

SELECT *
FROM `answers`
LEFT JOIN `spamlists` ON ( `spamlists`.`object_type` = 'Answer'
AND `spamlists`.`object_id` = `answers`.`id` )
WHERE `answers`.`question_id` =225
AND (
`spamlists`.`c_user_id` =72
AND `spamlists`.`object_id` = `answers`.`id`
)
LIMIT 0 , 30

Я получаю ровно те записи, что находятся в spamlists, а мне нужно наоборот. Получить все записи, исключая те, которые в spamlists.

★★★

Пытался ставить NOT перед вторым объеденённым условием, но тогда вообще ничего не возвращается.

VirRaa ★★★
() автор топика
Ответ на: комментарий от ihatetangotheme

Да, сначала хотел так. Но есть два ограничения:

1) CakePHP походу не работает с вложенными запросами.
2) IN имеет ограничения какое-то, то есть если там будет 500 символов, он не поймёт. Точное ограничение не помню.

VirRaa ★★★
() автор топика
Ответ на: комментарий от ihatetangotheme

> может тут что-то найдется http://book.cakephp.org/view/74/Complex-Find-Conditions ?

там внизу про sub-queries


а с EXCEPT можно было попробовать по id исключать


Спасибо за ссылку. Сделал, как там. И теперь меня интересует, есть ли разница между IN (SELECT `id` FROM `blah`) и IN (1,2,3,4,5,6,7,8,...,n);


Так как во втором случае, точно можно достигнуть лимита строки в конструкции IN.

VirRaa ★★★
() автор топика
Ответ на: комментарий от VirRaa

>есть ли разница между IN (SELECT `id` FROM `blah`) и IN (1,2,3,4,5,6,7,8,...,n);

В mysql, почему-то, первый вариант намного медленнее.

KRoN73 ★★★★★
()

А так не пробовал?:

SELECT *
FROM `answers`
LEFT JOIN `spamlists` ON `spamlists`.`object_id` <> `answers`.`id`
WHERE 
`spamlists`.`object_type` = 'Answer'
AND
`spamlists`.`c_user_id` =72
AND
`answers`.`question_id` =225

LIMIT 0 , 30

Attila ★★
()

Я получаю ровно те записи, что находятся в spamlists, а мне нужно наоборот. Получить все записи, исключая те, которые в spamlists.

а что тогда станет с `spamlists`.`c_user_id` = 72?

Вообще, если хочешь answers которые не в spamlists:

SELECT *
FROM `answers`
LEFT JOIN `spamlists` ON ( `spamlists`.`object_type` = 'Answer'
AND `spamlists`.`object_id` = `answers`.`id` )
WHERE 
   `spamlists`.`object_id` IS NULL 
  `answers`.`question_id` =225
AND 
  и что там еще
gods-little-toy ★★★
()

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

heisenberg ★★
()
Ответ на: комментарий от heisenberg

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

Йоба, ну иди и спрашивай. Хуле ты тут возникаешь?

VirRaa ★★★
() автор топика
Ответ на: комментарий от heisenberg

> быдлоподход, что в программировании, что по жизни

Ага. В жизни ещё бы я тебе по ебалу съездил.

VirRaa ★★★
() автор топика

ТС, использовать minus или [not] exists что-то не позволяет?

в твоем запросе после предложения ON явное условие на выборку из spamlist => получаешь только те записи, которые ему удовлетворяют

hotaru
()
Ответ на: комментарий от VirRaa

никак не получаются джойны у птушника васи. совсем запутался. уже сто раз пожалел, что отжал у студента на улице эту проклятую книгу «mysql для дебилов». ладно, вась, не расстраивайся, главное - читать не разучился! :)

heisenberg ★★
()
Ответ на: комментарий от Attila

> А так не пробовал?:

Это не сработает. Тут join получается invalid. Вообще с joinами нужно быть очень осторожными.

anonymous
()
Ответ на: комментарий от hotaru

> в твоем запросе после предложения ON явное условие на выборку из spamlist => получаешь только те записи, которые ему удовлетворяют

Нет, в том-то и дело. Для всех строк из левой таблицы, для которых не нашлось строк, удовлетворяющих условию, будут присоединены NULL'ы. Вот по этим NULLам и можно узнать, что ответ не в списке.

anonymous
()

[code] SELECT <field_list> FROM `answers` LEFT JOIN `spamlists` ON ( `spamlists`.`object_type` = 'Answer' AND `spamlists`.`object_id` = `answers`.`id` ) WHERE `answers`.`question_id` = 225 AND spamlist.id is NULL LIMIT 0 , 30 [/code]

может надо изменить в зависимости от того, что такое в spamlist c_user_id

qnikst ★★★★★
()
Ответ на: комментарий от anonymous

у ТС в предложении where условие на `spamlists`.`object_id`, и это не проверка на NULL

hotaru
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.