аналог "... NOT IN(SELECT ...)"

SashOk

Guest
аналог "... NOT IN(SELECT ...)"

Нужен аналог
SELECT * FROM table1 WHERE val NOT IN (SELECT val FROM table2)
ничего лучше пока не придумал:
PHP:
$qry = mysql_query('SELECT val FROM table2');
while($val = mysql_ferch_row($qry) )
   $vals[] = $val[0];
$qry = mysql_query(
   "SELECT * FROM table1 WHERE val NOT IN ('".
   join("', '", $vals)."')"
);
Медленно происходит.
 

Кром

Новичок
Если я правильно понял:
SELECT * FROM table1 LEFT JOIN table2 ON table1.val = table2.val WHERE table2.val IS NULL
 

clevel

Новичок
Кром, а если у меня в пхп массиве уже есть список id, которые not IN?
 

Кром

Новичок
>а если у меня в пхп массиве уже есть список id, которые not IN?

Такие списки должны лежать в базе. Объективных препятствий к этому нет. :)
 

Falc

Новичок
clevel
>>а если у меня в пхп массиве уже есть список id, которые not IN

Что тогда тебе мешает использовать NOT IN?

Только не понятно как это пересекается с заданым вопросом?
 

clevel

Новичок
Сорри, не было времени выйти в инет...
Банальная ситуация:
[sql]
CREATE TABLE test (
page tinyint(4) unsigned NOT NULL default '0',
book tinyint(4) unsigned NOT NULL default '0',
glava tinyint(4) unsigned NOT NULL default '0',
id tinyint(4) unsigned NOT NULL default '0',
ordinal tinyint(4) NOT NULL default '0',
KEY id (id,page,book,glava)
) TYPE=MyISAM;

INSERT INTO test VALUES (1, 0, 0, 200, 0);
INSERT INTO test VALUES (1, 1, 0, 150, 1);
INSERT INTO test VALUES (1, 0, 0, 44, 3);
INSERT INTO test VALUES (2, 0, 0, 200, 5);
INSERT INTO test VALUES (2, 0, 0, 150, 1);
INSERT INTO test VALUES (3, 0, 0, 200, 127);
[/sql]

Если я хочу вывести все книги, где есть id IN(200,150) и нет id NOT IN(44), то мне надо использовать такой запрос:
[sql]
SELECT DISTINCT t.page,t.book,t.glava FROM `test` t
LEFT JOIN test t2
ON t2.id IN(44)
AND t.page=t2.page
AND t.book=t2.book
AND t.glava=t2.glava
WHERE t.id IN(200,150)
AND t2.page IS NULL
[/sql]
Вариант, когда без объединения, но с использованием NOT IN не прокатывает:
[sql]
SELECT DISTINCT page,book,glava
FROM test
WHERE id IN(200,150)
AND id NOT IN(44)
[/sql]
 

Falc

Новичок
clevel
Ты сам запутался и путаешь других. Это совсем другая ситуация, и ничего общего с ситуацией описаной автором треда не имеет.
Если бы в мускуле были бы вложенные подзапросы ты бы ее все равно не решил NOT IN(SELECT ...).
В своей задаче ты накладываешь условия на разные записи поэтому тебе и нужны 2 таблицы.
 

clevel

Новичок
Falc
тогда я не понимаю смысл конструкции NOT IN...
объясните мне, дока настолько скудна, что понять из нее не представляется возможным...
Насколько я себе представляю логику, IN() используется для того, чтобы найти записи, в которые есть ХОТЯ БЫ одно из перечисленных в IN значений. NOT IN, соответсвенно, по идеи должна осекать все записи, в которых встретиться хотя бы одно из значений not in....
 

Falc

Новичок
clevel
Да ты все правильно сказал NOT IN нужно для исключения, что не понятно-то?
 

clevel

Новичок
тык мой пример
[sql]
SELECT DISTINCT page, book, glava
FROM test
WHERE id
IN ( 200, 150 ) AND id NOT
IN ( 44 )
[/sql]
не срабатывает... а по логике должен... почему я должен через left join это делать, если проще было бы сделать так?
И даже конструкция есть для этого, но что-то не то...
 

Falc

Новичок
clevel
>>не срабатывает... а по логике должен...

И по логике он не должен срабатывать.

id NOT IN ( 44 ) эквивалентно id <> 44

Все условия в WHERE накладываются одновременно на каждую запись.

В твоем случае условия на разные записи.
 
Сверху