Можно ли решить запросом? | |
---|---|
ry Автор Сообщений: 2113 Дата регистрации: 24.09.2007 |
Есть три таблицы (для примера сделаю три курсора с минимально необходимым количеством полей):
Нужно сделать выборку, отображающую различие в нормах расхода для изделий с одинаковым полем pro, сравнивая при этом записи для двух заданных значений left(code,4). Для записей с одинаковым left(code,4) значения поля pro уникальные. Например, требуется сравнить изделия с left(code,4)=="0101" и left(code,4)=="0201", в результате надо получить выборку, которая отобразит лишь не совпадающие значения: "01010001", "Любое название 1", "Материал 2", 5, "02010001", "Любое название 1", "Материал 2", 10 "01010001", "Любое название 1", "Материал 3", 10, "02010001", "Любое название 1", "Материал 3", 0 "01010001", "Любое название 1", "Материал 4", 0, "02010001", "Любое название 1", "Материал 4", 5 "01010002", "Любое название 2", "Материал 3", 10, "02010002", "Любое название 2", "Материал 3", 5 Решить без запросов смогу и сам, и вообще сомневаюсь, что здесь можно одним-двумя запросами обойтись, но если можно как-нибудь красиво извернуться, подскажите. |
Re: Можно ли решить запросом? | |
---|---|
AndyNigmatec Сообщений: 1574 Откуда: Волгоград Дата регистрации: 28.06.2015 |
Если я прально понял задачу, то полагаю в лоб так:
|
Re: Можно ли решить запросом? | |
---|---|
ry Автор Сообщений: 2113 Дата регистрации: 24.09.2007 |
Тему можно закрывать, уже реализовал через scan. Правда, время формирования отчета вышло около минуты (больше 20 тыс. изделий, больше сотни материалов, записей в нормах - более 500 тыс.). Но это не критично - выборка, можно считать, разовая.
|
Re: Можно ли решить запросом? | |
---|---|
ry Автор Сообщений: 2113 Дата регистрации: 24.09.2007 |
Сегодня не успеваю, завтра попробую проверить на реальных данных. |
Re: Можно ли решить запросом? | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Большого смысла писать "виртуальные" данные для различающихся материалов (там где null в курсоре) я не вижу. В принципе эти данные можно вывести, дописав ещё пару join по "странному" условию и брать поля code/name уже из g1 и g2 (если твоё уточнение про "уникальность" реально соблюдается)
Дублировать наименование материала тоже не вижу смысла (как я понял логику постановки задачи, они в конечном курсоре в одной записи идентичны должны быть). Структуры данных неоптимальна - если уж требуется работать по LEFT(good.CODE,4) то его стоило оформить отдельным полем. Тогда не нужен будет странноватый индекс по LEFT(good.CODE,4) для оптимизации такого рода запросов (или же играться с SET ANSI и длиной переменной, убрав LEFT из текста запроса - тогда и просто индекс по code поможет). Заодно можно сделать реально защищающий от "дубликатов по хитрому условию" candidate индекс - не плохо выглядящий LEFT(CODE,4)+pro а "красивый" code4+pro ------------------ WBR, Igor |
Re: Можно ли решить запросом? | |
---|---|
ry Автор Сообщений: 2113 Дата регистрации: 24.09.2007 |
To Igor Korolyov:
Почти то, что нужно. Дублировать название материала, конечно же, не обязательно. Это я просто в примере делал. Еще добавил отсев записей с пустым полем pro (то есть уникальности по полю на самом деле нет, так как пустые значения могут повторяться в пределах одного left(code,4). Проверил на реальных данных, работает быстро - 2-3 секунды. Правда, в выборку также попадают "лишние" изделия, которые есть только в одном из подзапросов (впрочем, таких оказалось не много, так что не проблема). А вот отобразить одновременно коды и названия изделий в обеих группах мне не удалось, что не понравилось заказчику. То есть хотелось бы полностью избавиться от NULL. Пока оставил свое решение как есть, время выполнения заказчика пока не напрягает. Структура таблиц и поля code не оптимальная, но "так исторически сложилось" - менять не могу, надо только анализировать данные. Индексы есть по всем полям в запросе (кроме количества), но нет индекса по left(code,4). Все равно запрос работает почти мгновенно. To AndyNigmatec: Немного не то - получается что-то вроде декартова произведения отобранных записей. |
Re: Можно ли решить запросом? | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Я имел в виду вот так добавлять код/имя для null-строк. Заодно использование INNER JOIN отбросит "изделия, которые есть только в одном из подзапросов".
Ну и оптимизация - раз структуру не поменять, то индекс по code можно вот таким финтом использовать - только обязательно задавать параметры 4-мя символами, иначе ANSI OFF и = не тот результат дадут.
------------------ WBR, Igor |
Re: Можно ли решить запросом? | |
---|---|
ry Автор Сообщений: 2113 Дата регистрации: 24.09.2007 |
Сегодня добрался поэкспериментировать. Время выполнения запроса на реальных данных возросло (в зависимости от начальных параметров выборки) где-то до 10 секунд и даже до полминуты. При SET ANSI OFF и сравнении по предложенному варианту 4 символов с полным полем через "=" на реальных данных получил неверные результаты. С чем это связано, разбираться не стал. При сравнении через left(code,4) и "==" результаты верные, но для некоторых пар lcCode1 и lcCode2 неожиданно получил ошибку "File ...tmp is too large". Я так понимаю, промежуточный запрос формирует временной файл, вылетающий за предел 2 ГБ. В общем, решил дальше не продолжать. Конечно, перебор сканом работает дольше (от одной до трех минут), но зато выдает нужный результат, а время выполнения пока не критично.
|
© 2000-2024 Fox Club  |