головоломный запрос (для меня)
головоломный запрос (для меня)
Состав таблиц:
tdogovor:
kl - numeric not null PK
bdj - numeric(3, 0)
tsveddog:
kl - numeric not null PK
dvid - varchar (хранит дату содержит значения ' . . ' - если дата не введена и собственно дату)
справочник
sprbdj:
kodbdj integer - содержит код бюджета, в tdogovor.bdj заносится код из этого справочника
bdj varchar - содержит название бюджета соответствующее полю kodbdj.
Возможно ли сделать запрос с таким смыслом:
мой запрос:
select count(kl), b.bdj,
sum(if (c.dvid <>' . . ') then 1 else 0 ) <-----такой смысл
from tdogovor a left join sprbdj b on a.bdj=b.kodbdj
left join tsveddog c on a.kl=c.kl
group by bdj
Мне надо чтобы возвращалось количество дат для каждой отдельной группы.
БД InterBase 6.0
Помогите пожалуйста начинающему.
tdogovor:
kl - numeric not null PK
bdj - numeric(3, 0)
tsveddog:
kl - numeric not null PK
dvid - varchar (хранит дату содержит значения ' . . ' - если дата не введена и собственно дату)
справочник
sprbdj:
kodbdj integer - содержит код бюджета, в tdogovor.bdj заносится код из этого справочника
bdj varchar - содержит название бюджета соответствующее полю kodbdj.
Возможно ли сделать запрос с таким смыслом:
мой запрос:
select count(kl), b.bdj,
sum(if (c.dvid <>' . . ') then 1 else 0 ) <-----такой смысл
from tdogovor a left join sprbdj b on a.bdj=b.kodbdj
left join tsveddog c on a.kl=c.kl
group by bdj
Мне надо чтобы возвращалось количество дат для каждой отдельной группы.
БД InterBase 6.0
Помогите пожалуйста начинающему.
если тебя сильно держит эта версия, что в общем то странно, то тогда только udf. А в FB 1.5 такое можно через case.БД InterBase 6.0
и еще комментарии:
1. наверное вместо numeric имелся в виду integer. не надо как в dbf. в SQL серверах если нужно целое число, просто пишут integer, а не numeric(3,0).
2. не переборщил ли ты с left join? а то как то странно все выглядит, по крайней мере не зная прикладной области...
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Что мешает использовать стандартный timestamp для дат и не парить мозги всякимии преобразованиями?dvid - varchar (хранит дату содержит значения ' . . ' - если дата не введена и собственно дату)
честно говоря нифига не понял как устроены таблицы и как они связаны... Еще разок по-русски для особо одаренных мона ?
Про ИБ 6 тоже уж сказано...
Всем спасибо за внимание к моему вопросу, извените что долго не мог ответить.
Насчет numeric то ты прав это надо пофиксить, спасибо.
Left join это у меня было от неизбежности, незнал как сделать такой запрос. А вообще все решилось очень просто, через использование хранимых процедур.
Если все еще интересно то все таблицы связаны по полю kl которое хранит код клиента, существует таблица tdogovor в которой это поле является уникальным, а остальные таблицы являются подчиненными. Вних может быть несколько записей принадлежащих одной записи таблицы tdogovor и соответственно будет несколько записей с обним значением в поле kl. Естественно в каждой таблице есть автоинкрементное поле.
Собственно такая версия InterBase используется поскольку она бесплатная (в моем регионе похоже что фиг кого разоришь на что-либо лицензионное), хотелось бы использовать FireBird, но приложение использует компоненты Delphi с политры InterBase, не будет ли каких проблем?kdv писал(а):если тебя сильно держит эта версия, что в общем то странно, то тогда только udf. А в FB 1.5 такое можно через case.БД InterBase 6.0
и еще комментарии:
1. наверное вместо numeric имелся в виду integer. не надо как в dbf. в SQL серверах если нужно целое число, просто пишут integer, а не numeric(3,0).
2. не переборщил ли ты с left join? а то как то странно все выглядит, по крайней мере не зная прикладной области...
Насчет numeric то ты прав это надо пофиксить, спасибо.
Left join это у меня было от неизбежности, незнал как сделать такой запрос. А вообще все решилось очень просто, через использование хранимых процедур.
Проблема моих дат состоит в том что заранее неизвестно будет пользователь вводить дату или оставит это поле незаполненным, то есть при сохранении придется или забивать левое значение, или делать сложный анализ в приложении при формировании запроса (вобще-то у меня в базе 12 таблиц, в каждой примерно 30 полей, от 10 до 15 из них даты), по этому пришлось так изголяться. Если есть способ более красивый и удобный то подскажите пожалуйста, т.к приложение и база пока в разработке то есть возможность поправить.Ivan_Pisarevsky писал(а):Цитата:
dvid - varchar (хранит дату содержит значения ' . . ' - если дата не введена и собственно дату)
Что мешает использовать стандартный timestamp для дат и не парить мозги всякимии преобразованиями?
честно говоря нифига не понял как устроены таблицы и как они связаны... Еще разок по-русски для особо одаренных мона ?
Если все еще интересно то все таблицы связаны по полю kl которое хранит код клиента, существует таблица tdogovor в которой это поле является уникальным, а остальные таблицы являются подчиненными. Вних может быть несколько записей принадлежащих одной записи таблицы tdogovor и соответственно будет несколько записей с обним значением в поле kl. Естественно в каждой таблице есть автоинкрементное поле.
Не, с этой поллитрой никаких проблем не будетAl-r писал(а): Собственно такая версия InterBase используется поскольку она бесплатная (в моем регионе похоже что фиг кого разоришь на что-либо лицензионное), хотелось бы использовать FireBird, но приложение использует компоненты Delphi с политры InterBase, не будет ли каких проблем?

Да ничего сложного. Основное тело запроса (Select ... From) укладывешь в какую-нибудь invisible мемку, при нажатии кнопки чтения после установки условий фильтрации складываешь его в .SQL запроса, добавляешь Add-ами текущее Where по состоянию контролов управления фильтрацией, не забываешь приaddить сзаду Order By, Group и Having если надо и открываешь.Al-r писал(а): Проблема моих дат состоит в том что заранее неизвестно будет пользователь вводить дату или оставит это поле незаполненным, то есть при сохранении придется или забивать левое значение, или делать сложный анализ в приложении при формировании запроса
"она бесплатная" - вы не в лесу живете?Собственно такая версия InterBase используется поскольку она бесплатная (в моем регионе похоже что фиг кого разоришь на что-либо лицензионное), хотелось бы использовать FireBird, но приложение использует компоненты Delphi с политры InterBase, не будет ли каких проблем?

насчет компонент - а попробовать? На сайте где-нибудь написано, что будут проблемы с IBX + Firebird?
В самом начале
http://www.ibase.ru/devinfo/ibx.htm
написано:
"С помощью IBX (и FIBPlus) можно работать с любыми версиями InterBase, Firebird и Yaffil."
вот же, сидят люди на глюкавом сервере пятилетней давности, и боятся каких то мифических проблем.

-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Что мешает использовать стандартную конструкциюПроблема моих дат состоит в том что заранее неизвестно будет пользователь вводить дату или оставит это поле незаполненным, то есть при сохранении придется или забивать левое значение, или делать сложный анализ в приложении при формировании запроса
"some_field is null"
"some_field is not null"
Пользую IBX, в паре с ФБ1.5.2 (перешел после иб6 уж почти год как) проблемы только если сам чего-нидь напортачу

Переход полностью исчерпал проблему со скоростью работы(самый долгий отчет собирается максимум секунд за пять, вместе с фетчем полученых записей), правда у меня размеры "детские" БД всего 100 мегов и таблиц меньше ста

например груп бай по одному полю, а ордер бай по другому.Возможны проблемы с уже работающими запросами
ИБ 6 такое пропускал, ФБ нет.
автору топика - Если четко не знаешь для чего тот или иной тип джойна предназначен, сделай их пока(на время учебы) неявными, файрберд вполне интелектуален чтоб все правильно приджойнить.не переборщил ли ты с left join? а то как то странно все выглядит, по крайней мере не зная прикладной области...
Код: Выделить всё
select count(kl), b.bdj,
sum(if (c.dvid <>' . . ') then 1 else 0 ) <-----такой смысл
from tdogovor a left join sprbdj b on a.bdj=b.kodbdj
left join tsveddog c on a.kl=c.kl
group by bdj
Код: Выделить всё
select count(kl), b.bdj,
from tdogovor a, sprbdj b, tsveddog c
where a.bdj=b.kodbdj and a.kl=c.kl and c.dvid is null
group by bdj