Как правильнее оформить запрос к БД?
4392
20
Вопрос к специалистам. Суть в следующем. У нас имеется некая таблица с довольно приличным количеством записей. Мы некоторым образом получили список id-шников (определенное количество от общего числа) этих записей - {a,b,c,d...z}
Теперь нужно получить данные из БД по этим id-шникам. Можно сделать это так:
SELECT column1,column2
FROM mytable
WHERE id=a OR id=b OR id=с .... OR id=z;
Однако, интуитивно, возникает подозрение, что длина строки ограничена, и при превышении определенного предела, СУБД выкинет ошибку.
В голову пришла другая мысль по реализации, выглядящая не так коряво (хотя, кому как):
Создаем временную табличку (CREATE TABLE TempTable и т.д.)
Загоняем в нее все наши id-шники INSERT-ом.
А затем делаем такой запрос
SELECT column1,column2
FROM mytable,TempTable
WHERE mytable.id=TempTable.id_temp;
Получили требуемые данные.
Затем DROP TABLE TempTable
В этом варианте, я практически гарантированно получаю результаты запроса, нисколько не опасаясь, что буфер переполнится (а переполнится ли он?). Но минус - этот способ намного медленнее. И при достаточно большом списке id-шников, запрос исполнятеся достаточно долго, что не удивительно. В первом же способе выполнятеся почти мгновенно.
Ну и наконец, интересно узнать, какой из способов предпочтительней, и есть ли другие варианты решения? Менять ER-модель не предлагать:улыб:
Viper
SELECT column1,column2
FROM mytable
WHERE id IN (x1, x2,...);

?
Михаил_1
А-а-а-а-а-а-а-а!!!!!!!!
Спасибо вам огромное! Блин, а я столько литературы перерыл и не нашел ни одного примера на подобный запрос, хотя подозревал, что должна же быть какая-то реализация! Я пытался сделать подобное, только вместо IN было =ANY, ну и естественно, не получалось! :respect: :respect: :respect:
Михаил_1
Указанный способ накладывает определенные ограничения. Для Oracle например не более 1000 при явном указании. А при подзапросе из другой таблицы таких ограничений нет.
DenFromNsk
Для того чтобы избежать этого ограничения можно воспользоваться указанным топикстартером вторым способом, с временной таблицей. Только запрос будет быстрее работать если писать
SELECT column1,column2
FROM mytable
inner join TempTable on mytable.id=TempTable.id_temp

Это я воспользовался тем, что во временной таблице ИД также уникален(нет двух строчек с одним ИД)
Дима553
2 DenFromNsk: Спасибо, не знал.:улыб:2 Дима553: Спасибо, буду иметь ввиду:улыб:Но для текущей реализации использовал предложение от Михаила, т.к. у меня вряд ли список ИДшников дойдет даже до 150. СУБД, кстати, MySQL
Дима553
> Только запрос будет быстрее работать если писать

Не думаю, что такой inner join будет сам по себе быстрее приводившегося выше простого select ... where ... Все дело всего лишь в индексах временной таблицы - или они есть, или их нет.
Viper
Как получили список Id?
Если тоже запросом то можно так:
SELECT column1,column2
FROM mytable
WHERE id IN (select id from.... where ...)
Сибиряк
Список ID был получен программным способом, не через запрос. Вложенные запросы мне известны:улыб:
Viper
Хм...странно. Знаете, как создавать таблицы, знаете про вложенные запросы, а про In() не знаете :dnknow:
Сибиряк
:dnknow: Ну бывает... Может быть, в свое время упустил тонкости. Профессионально с SQL раньше не работал. Т.е. теорию знаю - а вот практика иногда подводит, как видите.
Viper
Опять же не указана система. И не указано количество IDшников и не указаны критерии быстродействия.
В любом случае возможно было бы решить через временную таблицу. Либо через таблицу типов (для оракла).
Михаил_1
Помогите,пожалуйста, может я совсем непонятно опишу проблему, но попробую... :help.gif:
Создаю запрос в базу Oracle через Excel с параметрами, параметр в Экселе меняется вручную, данные должны обновляться по мере изменения значения параметра в ячейке.
Если вводишь одно значение параметра, например (304), данные обновляются нормально, но когда в параметр ставишь (304,211), то Эксель при обновлении не выдает результата.
В SQL Developer в аналогичном запросе указываешь
where dd.id in (304,211), нормально выводятся данные.
Почему параметр в Экселе через запятую не передается в базу?
Как мне отправить такую комбинацию через запрос в базу и чтобы он нормально вывел данные.... :шок:
nsk_nadin
Подозреваю, что значение в одной ячейке, Excel не передает как содержимое IN. Может попробовать объединить несколько ячеек в именованную область и в каждой отдельно писать одно число?
tolstopuz
Мне именно для пользователей надо , чтобы они в одну ячейку Экселя вводили через запятую idшники и им все считалось, похоже так не получится, думаю уже чтоли макрос писать надо с объединением нескольких ячеек...поможет или нет...вопрос...хотелось быстро сделать, а не заморачаиваться над этим:хммм:
nsk_nadin
сильно подозреваю что эксель считает запятую разделителем дробной части. В настройках поставьте разделитель точку вместо запятой
craxx
А он разве не догадывается, что несколько запятых в числе - это текстовый формат данных? Он же шибко вумный...:миг:
nsk_nadin
А что, у оракла трассировщика запросов нету?
craxx
В настройках где именно поставить точку вместо зяпятой? Туплю...:хммм:
nsk_nadin
если 2003 эксель
Сервис - Параметры - Международные
Числа - разделитель целой и дробной части
отключить галку "Использовать системные разделители" - и вместо запятой точку поставить
craxx
Мне так кажется, что еще и разделитель списков надо отрегулировать на запятую. Там помнится где-то точка с запятой пробегала...

А еще, при изменении этих значений с "умолчания", потом возникают проблемки при открытии чужих таблиц...:улыб: