FIRST 1 возвращает несколько записей

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
ALX

FIRST 1 возвращает несколько записей

Сообщение ALX » 15 ноя 2004, 13:42

Обнаружил интересную особенность в сл. запросе:
select * from TABLE1 where ID in
(select FIRST 1 fid from TABLE2 WHERE id =
(select FIRST 1 fid from TABLE3 where ID =
(select FIRST 1 fid from TABLE4 where id =
(select FIRST 1 id_table2 FROM LINKS_TABLE where id_table1=66))))

Запрос возвращет несколько записей, хотя во втором подзапросе явное указание на возврат одной записи.
Если прменить вместо "IN" знак "=", возвращается одна запись.
select * from TABLE1 where ID =
(select FIRST 1 fid from TABLE2 WHERE id =
(select FIRST 1 fid from TABLE3 where ID =
(select FIRST 1 fid from TABLE4 where id =
(select FIRST 1 id_table2 FROM LINKS_TABLE where id_table1=66))))


При этом в обоих случаях не выдается никаких ошибок. Меня в принципе такой результат устраивает, но остется ощущение неправильности.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 15 ноя 2004, 14:10

остается ощущение неправильности от такого запроса вообще :-)

Андрей Могильный
Сообщения: 12
Зарегистрирован: 26 окт 2004, 15:47

Re: FIRST 1 возвращает несколько записей

Сообщение Андрей Могильный » 15 ноя 2004, 15:22

ALX писал(а):select * from TABLE1 where ID in
(select FIRST 1 fid from TABLE2 WHERE id =


Подзапрос вернет 1 запись - это факт. А вот что верхний запрос вернет 1 запись - это не факт, т.к. в таблице table1 может быть несколько записей с ID=<значение которое вернул подзапрос>.
:lol:

ALX

Сообщение ALX » 15 ноя 2004, 15:30

В таблице TABLE1 на поле ID висит первичный ключ, так-что повторяющихся ID нет.

Гость

Сообщение Гость » 15 ноя 2004, 15:39

Между прочим запрос такой конструкции я использовал вместо запроса c объеденением:
select distinct TABLE1.*
from TABLE1, TABLE2, TABLE3, TABLE4, LINKS_TABLE
where (TABLE1.id=TABLE2.fid)
and (TABLE2.id=TABLE3.fid)
and (TABLE3.id=TABLE4.FID)
and (TABLE4.id=LINKS_TABLE.id_table2)
and (LINKS_TABLE.id_table1=66)

Так вот запрос с объеденением работает в 10 раз медленее (все-таки приходится все записи тащить). Так что хотелось бы разобраться до конца с операторм FIRST.

sag
Сообщения: 116
Зарегистрирован: 02 ноя 2004, 11:42

Сообщение sag » 15 ноя 2004, 15:42

Ахтунг!

To KDV:
Дима, каким бы странным не казался запрос, но
на fb1.5 запрос типа

select * from table_1 where table_1.id in
(select first 1
select table_2.id from table_2)

где table_1.id и table_2.id - первичные ключи
не обращает внимание на first 1 в подзапросе
(как будто его нет совсем).
Не смотря не "странность" запроса, сервер ведет себя
некорректно.
Может быть, конечно это хорошо известная фишка текущего поведения сервера, но я, честное слово, первый раз об этом слышу.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 15 ноя 2004, 15:51

sag писал(а):Может быть, конечно это хорошо известная фишка текущего поведения сервера, но я, честное слово, первый раз об этом слышу.
Релизные ноты читать пробовал? Иногда помогает...

sag
Сообщения: 116
Зарегистрирован: 02 ноя 2004, 11:42

Сообщение sag » 15 ноя 2004, 16:23

Прочитал, увидел. Упс. Был сбит с толку ответом о "ощущении неправильности" запроса. Пардон.
То есть IN всегда преобразуется в коррелированный EXISTS?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 15 ноя 2004, 16:57

коррелированый in преобразуется в такой же exists. в relnotes именно так и написано

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 15 ноя 2004, 19:51

sag писал(а):То есть IN всегда преобразуется в коррелированный EXISTS?
В текущих версиях всегда. Правда, не совсем в EXISTS, но детали тут не особо важны. Однако, при немного другом подходе это не помешает серверу все равно вывести правильный результат, но актуальность этой темы определяется уже следующими версиями сервера.

sag
Сообщения: 116
Зарегистрирован: 02 ноя 2004, 11:42

Сообщение sag » 16 ноя 2004, 08:41

sag> То есть IN всегда преобразуется в
sag> коррелированный EXISTS?
dimitr> В текущих версиях всегда.
dimitr> Однако, при немного другом подходе
dimitr> это не помешает серверу все равно вывести
dimitr> правильный результат, но актуальность
dimitr> этой темы определяется уже следующими
dimitr> версиями сервера.

ок, спасибо за разъяснения.

kdv> коррелированый in преобразуется в такой
kdv> же exists. в relnotes именно так и написано

угу. Именно это я и прочитал в нотах. Но речь шла
как раз о НЕКОРРЕЛИРОВАННОМ запросе. А он таким
же макаром преобразовался в коррелированную
конструкцию. И в relnotes как-то это не совсем
хорошо описано: речь идет о коррелированном "ИН",
а пример дан некоррелированного "ИН"а.

С уважением, sag

Ответить