Как правильнее оформить запрос к БД?
4419
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-модель не предлагать![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)
Теперь нужно получить данные из БД по этим 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-модель не предлагать
![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)
SELECT column1,column2
FROM mytable
WHERE id IN (x1, x2,...);
?
FROM mytable
WHERE id IN (x1, x2,...);
?
А-а-а-а-а-а-а-а!!!!!!!!
Спасибо вам огромное! Блин, а я столько литературы перерыл и не нашел ни одного примера на подобный запрос, хотя подозревал, что должна же быть какая-то реализация! Я пытался сделать подобное, только вместо IN было =ANY, ну и естественно, не получалось!
![:respect:](https://m.forum.ngs23.ru/static/img/graemlins/respect.gif)
Спасибо вам огромное! Блин, а я столько литературы перерыл и не нашел ни одного примера на подобный запрос, хотя подозревал, что должна же быть какая-то реализация! Я пытался сделать подобное, только вместо IN было =ANY, ну и естественно, не получалось!
![:respect:](https://m.forum.ngs23.ru/static/img/graemlins/respect.gif)
![:respect:](https://m.forum.ngs23.ru/static/img/graemlins/respect.gif)
![:respect:](https://m.forum.ngs23.ru/static/img/graemlins/respect.gif)
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
![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)
![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)
> Только запрос будет быстрее работать если писать
Не думаю, что такой 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 был получен программным способом, не через запрос. Вложенные запросы мне известны![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)
![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)
Хм...странно. Знаете, как создавать таблицы, знаете про вложенные запросы, а про In() не знаете ![:dnknow:](https://m.forum.ngs23.ru/static/img/graemlins/dntknw.gif)
![:dnknow:](https://m.forum.ngs23.ru/static/img/graemlins/dntknw.gif)
![:dnknow:](https://m.forum.ngs23.ru/static/img/graemlins/dntknw.gif)
Опять же не указана система. И не указано количество IDшников и не указаны критерии быстродействия.
В любом случае возможно было бы решить через временную таблицу. Либо через таблицу типов (для оракла).
В любом случае возможно было бы решить через временную таблицу. Либо через таблицу типов (для оракла).
Помогите,пожалуйста, может я совсем непонятно опишу проблему, но попробую... ![:help.gif:](https://m.forum.ngs23.ru/static/img/graemlins/help.gif)
Создаю запрос в базу Oracle через Excel с параметрами, параметр в Экселе меняется вручную, данные должны обновляться по мере изменения значения параметра в ячейке.
Если вводишь одно значение параметра, например (304), данные обновляются нормально, но когда в параметр ставишь (304,211), то Эксель при обновлении не выдает результата.
В SQL Developer в аналогичном запросе указываешь
where dd.id in (304,211), нормально выводятся данные.
Почему параметр в Экселе через запятую не передается в базу?
Как мне отправить такую комбинацию через запрос в базу и чтобы он нормально вывел данные....![:шок:](https://m.forum.ngs23.ru/static/img/graemlins/shocked.gif)
![:help.gif:](https://m.forum.ngs23.ru/static/img/graemlins/help.gif)
Создаю запрос в базу Oracle через Excel с параметрами, параметр в Экселе меняется вручную, данные должны обновляться по мере изменения значения параметра в ячейке.
Если вводишь одно значение параметра, например (304), данные обновляются нормально, но когда в параметр ставишь (304,211), то Эксель при обновлении не выдает результата.
В SQL Developer в аналогичном запросе указываешь
where dd.id in (304,211), нормально выводятся данные.
Почему параметр в Экселе через запятую не передается в базу?
Как мне отправить такую комбинацию через запрос в базу и чтобы он нормально вывел данные....
![:шок:](https://m.forum.ngs23.ru/static/img/graemlins/shocked.gif)
Подозреваю, что значение в одной ячейке, Excel не передает как содержимое IN. Может попробовать объединить несколько ячеек в именованную область и в каждой отдельно писать одно число?
Мне именно для пользователей надо , чтобы они в одну ячейку Экселя вводили через запятую idшники и им все считалось, похоже так не получится, думаю уже чтоли макрос писать надо с объединением нескольких ячеек...поможет или нет...вопрос...хотелось быстро сделать, а не заморачаиваться над этим![:хммм:](https://m.forum.ngs23.ru/static/img/graemlins/frown.gif)
![:хммм:](https://m.forum.ngs23.ru/static/img/graemlins/frown.gif)
сильно подозреваю что эксель считает запятую разделителем дробной части. В настройках поставьте разделитель точку вместо запятой
А он разве не догадывается, что несколько запятых в числе - это текстовый формат данных? Он же шибко вумный...![:миг:](https://m.forum.ngs23.ru/static/img/graemlins/wink.gif)
![:миг:](https://m.forum.ngs23.ru/static/img/graemlins/wink.gif)
А что, у оракла трассировщика запросов нету?
В настройках где именно поставить точку вместо зяпятой? Туплю...![:хммм:](https://m.forum.ngs23.ru/static/img/graemlins/frown.gif)
![:хммм:](https://m.forum.ngs23.ru/static/img/graemlins/frown.gif)
если 2003 эксель
Сервис - Параметры - Международные
Числа - разделитель целой и дробной части
отключить галку "Использовать системные разделители" - и вместо запятой точку поставить
Сервис - Параметры - Международные
Числа - разделитель целой и дробной части
отключить галку "Использовать системные разделители" - и вместо запятой точку поставить
Мне так кажется, что еще и разделитель списков надо отрегулировать на запятую. Там помнится где-то точка с запятой пробегала...
А еще, при изменении этих значений с "умолчания", потом возникают проблемки при открытии чужих таблиц...![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)
А еще, при изменении этих значений с "умолчания", потом возникают проблемки при открытии чужих таблиц...
![:улыб:](https://m.forum.ngs23.ru/static/img/graemlins/smile.gif)