Страница 1 из 1

Выборка из табл исключая данные др табл

Добавлено: 20 авг 2007, 15:15
Sparton
Помогите с запросом...
Выбрать из 1 таблицы данные только те, которых нет во 2 табл.

первая табл user (id, name)
вторая табл adress (id, id_user, adr)

Как вынуть id user-ов, которых нет во второй табл?

Re: Выборка из табл исключая данные др табл

Добавлено: 20 авг 2007, 15:46
Kotъ-Begemotъ
Sparton писал(а):Помогите с запросом...
Выбрать из 1 таблицы данные только те, которых нет во 2 табл.

первая табл user (id, name)
вторая табл adress (id, id_user, adr)

Как вынуть id user-ов, которых нет во второй табл?
Чет не понял. А в чём проблема?

Код: Выделить всё

select * from Table1
where not id in
(select id from Table2)

Добавлено: 20 авг 2007, 16:01
WildSery
Где всех учат плохому, "in (select)", "not in (select)"... :?
Есть хорошая штука exists, типа

Код: Выделить всё

select * from Table1
  where not exists (select id from Table2 where Table1.id = id)

Добавлено: 20 авг 2007, 16:05
Kotъ-Begemotъ
WildSery писал(а):Где всех учат плохому, "in (select)", "not in (select)"... :?
Есть хорошая штука exists, типа

Код: Выделить всё

select * from Table1
  where not exists (select id from Table2 where Table1.id = id)
Хм... Согласен что можно сделать и так. А в чём различие? Все равно ведь подзапрос выполняется сначала, а потом вхождения ищутся? Есть принципиальные отличия кроме синтаксиса?

Добавлено: 20 авг 2007, 16:26
WildSery
Отличие появилось в FB 2-ке и выше, ранее оптимизатор запросы с IN заменял на EXISTS сам, а теперь такие запросы выполняются через derived tables.
Время выполнения может отличаться на порядки, в зависимости от данных.

Добавлено: 20 авг 2007, 17:06
Sparton
WildSery писал(а): через derived tables.
Спасибо за подсказки, работает. Скоро будем ставить 2.0, как там использовать derived tables? Если быстрее работать будет.

Добавлено: 20 авг 2007, 18:15
WildSery
В этом конкретном, скорее всего, напоретесь на жуткий тормоз, если через IN написано, по сравнению с EXISTS.
При переходе на 2-ку все подзапросы через IN необходимо шерстить и проверять. А лучше сразу так не писать :)

Добавлено: 29 авг 2007, 08:19
Heimdallr
А так разве не классика жанра:

select u.* from user u
left join adress a on a.id_user=u.id
where a.id is null

Или подзапрос с exists все-таки лучше?

Добавлено: 29 авг 2007, 11:07
WildSery
Heimdallr писал(а):А так разве не классика жанра:
Это классика для систем, не поддерживающих подзапросы, например 1С.
Heimdallr писал(а):Или подзапрос с exists все-таки лучше?
Практически одинаково, но скорость exist >= скорости left join.
Как правило, равны, но бывают исключения.

У меня была ещё ситуация наоборот, когда left быстрее отрабатывал, но сейчас я её не помню, и потому склонен к мнению, что это у меня был глюк или неправильно что-то сравнивал.

Добавлено: 29 авг 2007, 13:40
Merlin
WildSery писал(а): У меня была ещё ситуация наоборот, когда left быстрее отрабатывал, но сейчас я её не помню, и потому склонен к мнению, что это у меня был глюк или неправильно что-то сравнивал.
Зависит от характера самих данных. В смысле соотношения случаев екзист и не екзист.

Добавлено: 29 авг 2007, 16:58
WildSery
Merlin писал(а):Зависит от характера самих данных.
А какое соотношение должно быть, не помнишь?
Чего-то попробовал на скорую руку - не получилось, чтобы left был быстрее.