Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Трабл с mysql

1.9K
15 июня 2004 года
Libarus
49 / / 30.10.2003
Есть такой запрос:

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 не пустые, есть хотябы по одной строке.
Как составить запрос так, чтобы все работало? И возможно ли сделать запрос проще и быстрее?
10
15 июня 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Libarus
Есть такой запрос:
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). В зависимости от того, на какой стороне предполагается отсутствие данных, различают левое и правое внешние объединение.

1.9K
16 июня 2004 года
Libarus
49 / / 30.10.2003
Цитата:
Originally posted by smartsoft

<..>Повторюсь еще раз, это зависит от задачи. Если требуется получить именно декартово произведение, оригинальная запись верна.<...>



Задача состоит в том, чтобы вывести все строки из таблицы t01 в которой значения поля id нет в столбцах idz таблиц t02 и t03. При пустых таблицах t02 и t03 таблица t01 выводиться полностью.

10
16 июня 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Libarus
Задача состоит в том, чтобы вывести все строки из таблицы t01 в которой значения поля id нет в столбцах idz таблиц t02 и t03. При пустых таблицах t02 и t03 таблица t01 выводиться полностью.


Надо попробовать так:

 
Код:
SELECT t01.*,t02.*,t03.*
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.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог