Выгрузка данных из БД по сложному условию
Для каждого множества создать временную таблицу с одним столбцом и данными из его элементов. В запросе вместо set1/set2 использовать вложенный select из врем. таблицы.
Спасибо за ответ, обновил первый пост. Прямого доступа к БД нет, работа идет через функции API, в которых используется псевдо-SQL.
а потом в памяти построить пересечение.а не лучше объединение строить?
вытащить for x in set1 do (field1 == x) and (field2 in set2) или вообще for x in set1 for y in set2 ?
ИМХО, нет, так как будет слишком много обращений к БД.
Первое решение, которое приходит в голову, следующее: разбить отдельно set1 и set2 на n1 и n2 подмножеств, выгрузить отдельно данные, а потом в памяти построить пересечение.а не пробовали сделать типа (x in set1_1 or x in set1_2 or ...) and (x in set2_1 or ...)?
подмножества раскидать по разным кускам, чтоб парсер не захлёбывался, а в итоге всё равно один запрос.
1. Пересмотреть архитектуру системы. Раз приходится передавать большие выборки то скорее всего в какой-то момент функции БД переложили на приложение.
2. Сделать двойной цикл но не по одной записи а по подмножеству (определить на скольких записях ломается и бить множества set1 и set2 на подмножества заданного размера)
3. Точно не уверен но может прокатить:
select * from table where
field1 in
(select item1_1
union all
select item1_2
...здесь все элементы из set1
)
and
field2 in
(select item2_1
union all
select item2_2
...здесь все элементы из set2
)
мне кажется лучше объединять чем пересекать. пересекать самому может не получиться, пересечение может быть маленьким, а множества до пересечения могут оказаться огромными.
com.jnetdirect.jsql.u: The server encountered a stack overflow during compile time.странная ошибка для режима выполнения
ты уверен, что с запросом все в порядке? (синтаксические ошибки или алгоритмические)
, нет не пробовали, но похоже, что захлебывается парсер скуля, поэтому описанный способ не поможет. Ниже я приведу ссылку на аналогичную проблему, там возникает такая же ошибка, при другом запросе.
, архитектуру пересмотреть нельзя, работа с БД идет через функции API. Большие выборки приходится делать, потому что необходимо получить много данных. Про двойной цикл уже писали. Мне кажется, что работать будет дольше, потому что будет слишком много запросов к БД.
, если множества разбить на m и n частей, то для объединения надо будет делать m x n запросов, а для пересечения — m + n.
, в гугле по первой ссылке находится точно такая же ошибка, возникающая при выполнении длинного запроса, поэтому, думаю, проблема точно в длине запроса.
set1 и set2 могут быть очень большими множествами, поэтому, если решать в лоб, то SQL-запрос получается слишком длинным и запрос вылетает с ошибкойдумал, что set1 описывает большой рекордсет, а оказалось, что set1 - это подзапрос из большого числа буковок
, нет не пробовали, но похоже, что захлебывается парсер скуля, поэтому описанный способ не поможет. Ниже я приведу ссылку на аналогичную проблему, там возникает такая же ошибка, при другом запросе.именно потому что захлёбывается парсер скуля (или кто-нибудь ещё описанный способ сработает. Имо, выражения типа (<element>{,<element>}) разбираются рекурсией, которая и заходит слишком глубоко. Если было N элементов, то выражение x in (set1) закопает парсер на глубину N+1, а выражение x in (set1_1) or x in (set1_2 где оба множества - половинки исходного, даст глубину N/2 + 2 - явно меньше исходного.
Спасибо за объяснение, теперь понял, почему может помочь разбиение на подмножества при одном запросе. Ну что же, проведу небольшой эксперимент, когда появится время, и соощу о результате.
SELECT * FROM Drug
WHERE ([DrugKey] = 1 AND Year = 1995)
OR ([DrugKey] = 1 AND Year = 1996)
OR ([DrugKey] = 1 AND Year = 1997)
OR ([DrugKey] = 1 AND Year = 1998)
OR ([DrugKey] = 1 AND Year = 1999)
OR ([DrugKey] = 1 AND Year = 2000)
OR ([DrugKey] = 1 AND Year = 2001)
OR ([DrugKey] = 1 AND Year = 2002)
OR ([DrugKey] = 10017 AND Year = 1995)
OR ([DrugKey] = 10018 AND Year = 1997)
...
На нем парсер не должен захлебнуться в рекурсии.
Оставить комментарий
saveliev_a
Всем привет.Есть такая вот задача. Нужно вытащить данные из БД по следующему условию
set1 и set2 могут быть очень большими множествами, поэтому, если решать в лоб, то SQL-запрос получается слишком длинным и запрос вылетает с ошибкой
Первое решение, которое приходит в голову, следующее: разбить отдельно set1 и set2 на n1 и n2 подмножеств, выгрузить отдельно данные, а потом в памяти построить пересечение.
Может быть, будут идеи получше?
СУБД MSSQL.
UPD. Прямого доступа к БД нет, работа идет через функции API, в которых используется псевдо-SQL.