| imho.ws |
![]() |
|
|
|
# 1 |
|
Junior Member
Регистрация: 19.05.2003
Адрес: Самара
Сообщения: 52
![]() |
ПОмогите переделать запрос
Надо переделать запрос, чтоб быстро работал. Дело в том, что если объединять INNER JOIN и OUTER JOIN то почему-то выскакиевает ошибка о невозможности прочетать кусок памяти. Ошибка вылазит и в DBD и в SQL Bilder (тот, что в дельфи встроен). Если везде оставить внешнее соединение, то работае пол дня. Желательно решения в одном запросе, без представлений и т.п. если это конечно возможно.
Речь идет о локальной БД парадокс, работает через БДЕ. D6 c апдейтами. Такой вариант работает, но уж больно долго.... Никак не придумаю, что с ним можно сделать ![]() /* ALIAS: dbTabel */ SELECT Sotrudniki.So_Family Фамилия, Sotrudniki.So_Name И, Sotrudniki.So_Otchestvo О, Sotrudniki.So_Tabel_Num Sotrudniki."Таб. №", Dolgnosti.D_Name Должность, Sostav_otdelov.Sos_Razryad Разряд, COUNT( T.T_Label_Code ) T."Дни явок", SUM( T.T_Label_Code ) Отработано, COUNT( T2.T_Label_Code ) T2."Дни неявок" FROM "Sotrudniki.DB" Sotrudniki LEFT OUTER JOIN "Sostav_Otdelov.DB" Sostav_otdelov ON (Sotrudniki.So_Code = Sostav_otdelov.Sos_Sotrudnik_Code) LEFT OUTER JOIN "Dolgnosti.DB" Dolgnosti ON (Sostav_otdelov.Sos_Dolgnost_Code = Dolgnosti.D_Code) LEFT OUTER JOIN "Tabel.DB" Tabel ON (Tabel.T_Sotr_Code = Sostav_otdelov.Sos_Sotrudnik_Code) LEFT OUTER JOIN "Tabel.DB" T ON (T.T_Sotr_Code = Tabel.T_Sotr_Code) AND (T.T_Data = Tabel.T_Data) AND (T.T_Label_Code < 9) LEFT OUTER JOIN "Tabel.DB" T2 ON (T2.T_Sotr_Code = Tabel.T_Sotr_Code) AND (T2.T_Data = Tabel.T_Data) AND (T2.T_Label_Code > 8) WHERE Tabel.T_Data BETWEEN CAST( '1.01.2003' AS DATE ) AND CAST( '31.01.2003' AS DATE ) AND (Sostav_otdelov.Sos_Otdel_Code = 1) GROUP BY Sotrudniki.So_Name, Sotrudniki.So_Otchestvo, Sotrudniki.So_Tabel_Num, Sostav_otdelov.Sos_Razryad, Sotrudniki.So_Family, Dolgnosti.D_Name, Dolgnosti.D_Name |
|
|
|
|
# 2 |
|
Guest
Сообщения: n/a
|
Вот чего у меня получилось:
главная идея в том, чтобы избавиться от JOIN потому, как этот вариант мне выгодным не кажется (сначала делаем гигантскую таблицу по условиям через JOIN, а потом на нее еще условия накладываем - долго). SELECT Sotrudniki.So_Family Фамилия, Sotrudniki.So_Name И, Sotrudniki.So_Otchestvo О, Sotrudniki.So_Tabel_Num Sotrudniki."Таб. №", Dolgnosti.D_Name Должность, Sostav_otdelov.Sos_Razryad Разряд, COUNT( T.T_Label_Code ) T."Дни явок", SUM( T.T_Label_Code ) Отработано, COUNT( T2.T_Label_Code ) T2."Дни неявок" FROM "Sotrudniki.DB" Sotrudniki, "Sostav_Otdelov.DB" Sostav_otdelov, "Dolgnosti.DB" Dolgnosti, "Tabel.DB" Tabel, "Tabel.DB" T, "Tabel.DB" T2 WHERE Sotrudniki.So_Code = Sostav_otdelov.Sos_Sotrudnik_Code AND Sostav_otdelov.Sos_Dolgnost_Code = Dolgnosti.D_Code AND Tabel.T_Sotr_Code = Sostav_otdelov.Sos_Sotrudnik_Code AND /* Если в таблице "Tabel.DB" нет PRIMARY KEY, то самое время его туда добавить следующие 2 условия заменятся на 1 */ T.T_Sotr_Code = Tabel.T_Sotr_Code AND T.T_Data = Tabel.T_Data AND T.T_Label_Code < 9 AND /* Тоже самое насчет PRIMARY KEY */ T2.T_Sotr_Code = Tabel.T_Sotr_Code AND T2.T_Data = Tabel.T_Data AND T2.T_Label_Code > 8 AND /* По стандарту (вроде ;-) ) SQL92 оно и без CAST должно работать */ Tabel.T_Data BETWEEN '1.01.2003' AND '31.01.2003' AND Sostav_otdelov.Sos_Otdel_Code = 1 GROUP BY Sotrudniki.So_Name, Sotrudniki.So_Otchestvo, Sotrudniki.So_Tabel_Num, Sostav_otdelov.Sos_Razryad, Sotrudniki.So_Family, Dolgnosti.D_Name, Dolgnosti.D_Name |
|
|
# 3 |
|
Junior Member
Регистрация: 28.10.2003
Адрес: Украина
Сообщения: 57
![]() ![]() |
Второй запрос не идентичен первому, так как в первом используется внешнее обьединение а во втором внутренное. Убыстрить его врядли получится (по крайней мере я не знаю как) но можно разбить на два (или больше в зависимости от ситуации) запроса попроще и на клиенте локейтится.
Для передачи дат в запрос не используй CAST, передавай как параметры. |
|
|
|
|
# 4 | ||
|
Junior Member
Регистрация: 19.05.2003
Адрес: Самара
Сообщения: 52
![]() |
Цитата:
![]() Только вот в следующих строчках собака порылась, и выходит, что вывода никакого не будет, т.к. не пересекаются эти условия ![]() Цитата:
![]() ППС: Списибо за то, что хоть откликнулся! Добавлено через 6 минут: PVitaliy Про неидентичность это ты прав Он вообще ничего не выводит...Разбивать не желательно, но похоже, придется с этим смириться ![]() Про клиента не понял... БД то локальная... Причем тут клиент? Без каста не получается. Как параметры и передаю, просто я сюда положил отладочный вариант. ДБД и СКуЛ Билдер не понимают параметры, поэтому я их и заменил на время отладки. А параметры без каста не принимаются... почему-то... типы вроде совпадают... |
||
|
|
|
|
# 5 |
|
Guest
Сообщения: n/a
|
Felan
Прости пожалуйста, но ты пробовал то, о чем говоришь? Я имею ввиду, что то, что я привел - не работает. Tabel.T_Data AND T.T_Label_Code < 9 AND Tabel.T_Data AND T.T_Label_Code > 8 AND не будет работать - это точно, а Tabel.T_Data AND T.T_Label_Code < 9 AND Tabel.T_Data AND T2.T_Label_Code > 8 AND обязано работать (или у меня СУБД неправильная - что вряд ли!) "Tabel.DB" под ALIASом Table, T, T2 - это разные таблицы, на которые условия накладываются отдельно и независимо! А насчет первого решения, пришедшего мне в голову - тут ты прав. Мне пришла мысль по упрощению - я ее написал. Если ты рассчитываешь, что кто-то станет над твоим вопросом несколько дней голову ломать и гору литературы перерывать - ты КРУПНО ошибся! |
|
|
# 6 | |||||
|
Junior Member
Регистрация: 19.05.2003
Адрес: Самара
Сообщения: 52
![]() |
Цитата:
Цитата:
![]() Если ты внимательно посмотришь мою предыдущую квоту, то увидишь, что там именно про Т2 речь и идет. Так что я все правильно сделал. Не прав ты. Хотя... возможно я не туда смотрел, но счас еще раз все перепроверил, и снова утверждаю, что этот запрос не имеет никакого вывода по той же причине!!! Так вот, если все-таки гоню я, то ты меня ткни носом пожалуйста, как должны быть организованы эти условия? Цитата:
Цитата:
Цитата:
Подводя итог: Если ты уверен, что это должно рабоатать, то объясни подробнее, потому, что я не нашел способа заставить работать запрос в твоем варианте! Если ты не уверен, то не спорь и проверь сам о чем говоришь. (Я так понял, что ты его не тестил, а просто в голове преобразовал). Если тебе интересно, могу выслать структуры таблиц, или даже сами таблици, только мыло оставь или аську. Если ты не можешь больше сказать ничего конструктивного, то давай закроем тему. Незачем бестолково спорить. |
|||||
|
|
|
|
# 7 |
|
Guest
Сообщения: n/a
|
Felan
Ясно, сорри. Я думал, ты мне говоришь, что я написал первое, что пришло в голову, не подумав. Ты прав, я не проверял этот запрос - твоей БД у меня нет , просто подобный вариант у меня работает. Но я все еще не согласен, что он не работает по той причине, на которую ты указал, а потому вышли мне скрипт твоей БД на мыло dsvrv@mail.ru (самому интересно, в чем там дело ). Заодно, скажи-ка, какая у тебя СУБД.
|
|
|
# 8 |
|
Junior Member
Регистрация: 19.05.2003
Адрес: Самара
Сообщения: 52
![]() |
SpacerV
Видишь ли, скрипт я тебе не пришлю, т.к. нет его Я на делфи интерфейс делаю.СУБД я в первом сообщении говорил Paradox, работаю через BDE.Так что сам понимаешь, sql тут не самой хорошей версии ![]() Могу выслать тебе только таблици, сам запрос уже есть. Если с дельфи работатешь, запросы можно будет где посмотреть, если нет, то и смысла нету в этом. Правдо мне тут пришлось немного структуру переделать... Но, вроде на суть проблемы это не повлияло. Я на нее просто забил и пошел обходным путем. Таблицы я вложил сюда.
__________________
Когда у оппонента кончаются аргументы, он начинает уточнять национальность. |
|
|
|
|
# 9 |
|
Guest
Сообщения: n/a
|
Felan
М-да . Внутренним объединением девствительно никак. Пришел я к такой структуре:SELECT Sotrudniki.So_Tabel_Num Sotrudniki."Tab No", COUNT( T.T_Label_Code ) T."TabOn", SUM( T.T_Label_Code ) Îòðàáîòàíî, COUNT( T2.T_Label_Code ) T2."TabOff" FROM "Sotrudniki.DB" Sotrudniki, "Sostav_Otdelov.DB" Sostav_otdelov, "Tabel.DB" T, "Tabel.DB" T2 WHERE Sotrudniki.So_Code = Sostav_otdelov.Sos_Sotrudnik_Code AND T.T_Sotr_Code = Sostav_otdelov.Sos_Sotrudnik_Code AND T.T_Label_Code < 9 AND T2.T_Sotr_Code = T.T_Sotr_Code AND T2.T_Label_Code > 8 AND T.T_Data BETWEEN '1.01.2003' AND '31.01.2003' AND T2.T_Data BETWEEN '1.01.2003' AND '31.01.2003' AND Sostav_otdelov.Sos_Otdel_Code = 1 GROUP BY Sotrudniki.So_Tabel_Num и увидел, что все равно для каждой записи из T будут браться все записи из Т2 и от этого не избавиться. Sorry! |