Трабл с mysql
SELECT `t01`.*,`t02`.*,`t03`.*
FROM `t01`,`t02`,`t03`
WHERE (`t01`.`otk`=2) AND
(`t01`.`idu`<>5) AND
(`t01`.`id`<>`t02`.`idz`) AND
(`t01`.`id`<>`t03`.`idz`);
Фишка в том, что запрос должен вывести все строки из таблицы t01 в которых id не совпадает ни в таблице t02 ни в тиблице t03. Он срабатывает только тогда когда t02 и t03 не пустые, есть хотябы по одной строке.
Как составить запрос так, чтобы все работало? И возможно ли сделать запрос проще и быстрее?
Есть такой запрос:
SELECT `t01`.*,`t02`.*,`t03`.*
FROM `t01`,`t02`,`t03`
WHERE (`t01`.`otk`=2) AND
(`t01`.`idu`<>5) AND
(`t01`.`id`<>`t02`.`idz`) AND
(`t01`.`id`<>`t03`.`idz`);
Не уверен, что запись вида t01.id<>t02.idz верна с точки зрения SQL. Дело в том, что в SQL выражения неравенства для двух столбцов являются полной инверсией равенства, т. е. выводятся все комбинации двух полей, не попададающие под выражения равенства. Получается вроде неявного декартова произведения. Естественно, это сильно замедляет работу сервера и увеличивает расход памяти.
Чтобы обойти проблему, неравенства чаще всего записывают как not t01.id = t02.idz. Повторюсь еще раз, это зависит от задачи. Если требуется получить именно декартово произведение, оригинальная запись верна.
Он срабатывает только тогда когда t02 и t03 не пустые, есть хотябы по одной строке.
Выражения равенства и неравенства по умолчанию работают как объединение (join), или пересечение множеств. Если хотя бы на одной стороне нет данных, условие считается невыполненным.
Чтобы условие выполнялось при отсутствии данных на одной из сторон выражения, существует внешнее объединение. Не уверен, поддерживает ли MySQL такой синтаксис:
t01.id = t02.idz (+) (это синтаксис Oracle). В зависимости от того, на какой стороне предполагается отсутствие данных, различают левое и правое внешние объединение.
<..>Повторюсь еще раз, это зависит от задачи. Если требуется получить именно декартово произведение, оригинальная запись верна.<...>
Задача состоит в том, чтобы вывести все строки из таблицы t01 в которой значения поля id нет в столбцах idz таблиц t02 и t03. При пустых таблицах t02 и t03 таблица t01 выводиться полностью.
Задача состоит в том, чтобы вывести все строки из таблицы t01 в которой значения поля id нет в столбцах idz таблиц t02 и t03. При пустых таблицах t02 и t03 таблица t01 выводиться полностью.
Надо попробовать так:
FROM t01,t02,t03
WHERE t01.otk = 2 AND
t01.idu <> 5 AND
not t01.id = t02.idz (+) AND
not t01.id = t03.idz (+);
Если такой синтаксис не поддерживается, придется переписать запрос с использованием ключевых слов RIGHT OUTER JOIN.