Как правильнее оформить запрос к БД?
4394
20
Viper
activist
Вопрос к специалистам. Суть в следующем. У нас имеется некая таблица с довольно приличным количеством записей. Мы некоторым образом получили список 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-модель не предлагать
Теперь нужно получить данные из БД по этим 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-модель не предлагать
SELECT column1,column2
FROM mytable
WHERE id IN (x1, x2,...);
?
FROM mytable
WHERE id IN (x1, x2,...);
?
А-а-а-а-а-а-а-а!!!!!!!!
Спасибо вам огромное! Блин, а я столько литературы перерыл и не нашел ни одного примера на подобный запрос, хотя подозревал, что должна же быть какая-то реализация! Я пытался сделать подобное, только вместо IN было =ANY, ну и естественно, не получалось!
Спасибо вам огромное! Блин, а я столько литературы перерыл и не нашел ни одного примера на подобный запрос, хотя подозревал, что должна же быть какая-то реализация! Я пытался сделать подобное, только вместо IN было =ANY, ну и естественно, не получалось!
DenFromNsk
activist
Указанный способ накладывает определенные ограничения. Для Oracle например не более 1000 при явном указании. А при подзапросе из другой таблицы таких ограничений нет.
Дима553
experienced
Для того чтобы избежать этого ограничения можно воспользоваться указанным топикстартером вторым способом, с временной таблицей. Только запрос будет быстрее работать если писать
SELECT column1,column2
FROM mytable
inner join TempTable on mytable.id=TempTable.id_temp
Это я воспользовался тем, что во временной таблице ИД также уникален(нет двух строчек с одним ИД)
SELECT column1,column2
FROM mytable
inner join TempTable on mytable.id=TempTable.id_temp
Это я воспользовался тем, что во временной таблице ИД также уникален(нет двух строчек с одним ИД)
2 DenFromNsk: Спасибо, не знал.2 Дима553: Спасибо, буду иметь ввидуНо для текущей реализации использовал предложение от Михаила, т.к. у меня вряд ли список ИДшников дойдет даже до 150. СУБД, кстати, MySQL
> Только запрос будет быстрее работать если писать
Не думаю, что такой inner join будет сам по себе быстрее приводившегося выше простого select ... where ... Все дело всего лишь в индексах временной таблицы - или они есть, или их нет.
Не думаю, что такой inner join будет сам по себе быстрее приводившегося выше простого select ... where ... Все дело всего лишь в индексах временной таблицы - или они есть, или их нет.
Как получили список Id?
Если тоже запросом то можно так:
SELECT column1,column2
FROM mytable
WHERE id IN (select id from.... where ...)
Если тоже запросом то можно так:
SELECT column1,column2
FROM mytable
WHERE id IN (select id from.... where ...)
Список ID был получен программным способом, не через запрос. Вложенные запросы мне известны
Хм...странно. Знаете, как создавать таблицы, знаете про вложенные запросы, а про In() не знаете
Ну бывает... Может быть, в свое время упустил тонкости. Профессионально с SQL раньше не работал. Т.е. теорию знаю - а вот практика иногда подводит, как видите.
Опять же не указана система. И не указано количество IDшников и не указаны критерии быстродействия.
В любом случае возможно было бы решить через временную таблицу. Либо через таблицу типов (для оракла).
В любом случае возможно было бы решить через временную таблицу. Либо через таблицу типов (для оракла).
Помогите,пожалуйста, может я совсем непонятно опишу проблему, но попробую...
Создаю запрос в базу Oracle через Excel с параметрами, параметр в Экселе меняется вручную, данные должны обновляться по мере изменения значения параметра в ячейке.
Если вводишь одно значение параметра, например (304), данные обновляются нормально, но когда в параметр ставишь (304,211), то Эксель при обновлении не выдает результата.
В SQL Developer в аналогичном запросе указываешь
where dd.id in (304,211), нормально выводятся данные.
Почему параметр в Экселе через запятую не передается в базу?
Как мне отправить такую комбинацию через запрос в базу и чтобы он нормально вывел данные....
Создаю запрос в базу Oracle через Excel с параметрами, параметр в Экселе меняется вручную, данные должны обновляться по мере изменения значения параметра в ячейке.
Если вводишь одно значение параметра, например (304), данные обновляются нормально, но когда в параметр ставишь (304,211), то Эксель при обновлении не выдает результата.
В SQL Developer в аналогичном запросе указываешь
where dd.id in (304,211), нормально выводятся данные.
Почему параметр в Экселе через запятую не передается в базу?
Как мне отправить такую комбинацию через запрос в базу и чтобы он нормально вывел данные....
Подозреваю, что значение в одной ячейке, Excel не передает как содержимое IN. Может попробовать объединить несколько ячеек в именованную область и в каждой отдельно писать одно число?
Мне именно для пользователей надо , чтобы они в одну ячейку Экселя вводили через запятую idшники и им все считалось, похоже так не получится, думаю уже чтоли макрос писать надо с объединением нескольких ячеек...поможет или нет...вопрос...хотелось быстро сделать, а не заморачаиваться над этим
сильно подозреваю что эксель считает запятую разделителем дробной части. В настройках поставьте разделитель точку вместо запятой
А он разве не догадывается, что несколько запятых в числе - это текстовый формат данных? Он же шибко вумный...
А что, у оракла трассировщика запросов нету?
В настройках где именно поставить точку вместо зяпятой? Туплю...
если 2003 эксель
Сервис - Параметры - Международные
Числа - разделитель целой и дробной части
отключить галку "Использовать системные разделители" - и вместо запятой точку поставить
Сервис - Параметры - Международные
Числа - разделитель целой и дробной части
отключить галку "Использовать системные разделители" - и вместо запятой точку поставить
Мне так кажется, что еще и разделитель списков надо отрегулировать на запятую. Там помнится где-то точка с запятой пробегала...
А еще, при изменении этих значений с "умолчания", потом возникают проблемки при открытии чужих таблиц...
А еще, при изменении этих значений с "умолчания", потом возникают проблемки при открытии чужих таблиц...