Форум: "Базы";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];
ВнизСозание фильтра Найти похожие ветки
← →
Lucky[ELF] (2004-01-27 20:22) [0]Есть запрос типа:
SET NAMES WIN1251;
CONNECT "Homecode-mrf5gu:rev2.gdb"
USER "SYSDBA" PASSWORD "masterkey";
select KR.ID_KREDIT, P.ID_PEOPLE, P.SERNAME, P.NAME, P.PNAME,
PC.CHET, SC.SUB_CHET, V.ID_VALUTA, FC.KEY_NUM, B.BASE_NUMBER, FC.CHET_NUM,
KR.SUMM, KR.DOG_DATE, KR.DOG_NUM, F.NUMBER, KR.STATUS, KR.REAL_POG_DATE
from T_KREDIT KR, T_FULL_CHET FC, T_PEOPLE P, T_BANK B, T_FILIAL F,
T_PLAN_CHET PC, T_SUB_CHET SC, T_VALUTA V, T_CHET_SYMBOL CS
WHERE P.ID_PEOPLE = KR.ID_PEOPLE AND
FC.ID_FULL_CHET = KR.ID_FULL_CHET AND
FC.BASE_NUMBER = B.BASE_NUMBER AND
FC.ID_VALUTA = V.ID_VALUTA AND
FC.ID_CHET_SYMBOL = CS.ID_CHET_SYMBOL AND
SC.ID_SUB_CHET = CS.ID_SUB_CHET AND
SC.CHET = PC.CHET AND
KR.ID_FILIAL = F.ID_FILIAL AND
F.BASE_NUMBER = B.BASE_NUMBER
ORDER BY P.ID_PEOPLE, KR.STATUS
Этот запрос выдает полную информацию из всей базы. Теперь скажем, если надо выдать инфу за определенный период, то в него надо добавить сравнение по дате (никаких проблем), если надо выбрать кортеже с опеределенной суммой или выше или ниже определенной или исключая определенну сумму, или выдать кортеже с определенным статусом или исключая этот статус, или записи конкретного человека (по фамилии) или по не полной фамилии (Иванов, Иванова, Ивановский, Иванычев -> "Иван%"), вообщем таких полей по которым можно производить сортировку около 10-15, кроме того, чтобы запрос не работал очень долго - если записей скажем 100 000, то есть еще ограничитель на выходную последовательность например не более 100 - он тоже меняется, после чего запрос выполняется заново (наверное) и выдает заданное количестов записей. Кроме всего этого возникает ситуации когда следует фильтровать почти по всем полям (из определенного набора).
- ПОДОБНЫЙ фильтр я видел в крупной коммерческой системе.
Вот хотелось бы сделать такое же, Но один запрос у меня не получается по той причине, что не известно какие поля будут участвовать и как по ним будет сравниваться, сортироваться и etc
Мне пришел в голову :) только один вариант - это сделать генерацию запроса динамически, например так (из старых работ с BDE):
SelectVacQuery.Close;
SelectVacQuery.SQL.Clear;
SelectVacQuery.SQL.Add("SELECT C.ID, C.SUR_NAME, C.NAME, C.SECOND_NAME,");
SelectVacQuery.SQL.Add("C.AGE, C.ADRESS,");
SelectVacQuery.SQL.Add("C.PASSPORT_SERIES, C.PASSPORT_NUMBER,");
SelectVacQuery.SQL.Add("C.PASSPORT_ISSUED, C.PASSPORT_DATE,");
SelectVacQuery.SQL.Add("C.REG_DATE, C.SALARY,");
SelectVacQuery.SQL.Add("F.FORMATION, F.INSTITUTION,");
SelectVacQuery.SQL.Add("F.DIPLOM_NUMBER, F.YEAR_COMPLETE,");
SelectVacQuery.SQL.Add("P.PROFESSION, P.CATHEGORY, P.STAG,");
SelectVacQuery.SQL.Add("E.PROFESSION, E.CATHEGORY, E.STAG,");
SelectVacQuery.SQL.Add("E.SALARY, E.FORMATION, E.JOB_TITLE,");
SelectVacQuery.SQL.Add("S.ENT_PRISE, S.ID, E.Profession_ID");
SelectVacQuery.SQL.Add("FROM CLIENTS.db C, FORMATIONS.db F, PROFESSIONS.DB P, EPROFESSIONS.DB E, enterprises.db S");
SelectVacQuery.SQL.Add("WHERE ((C.ACTIVE_CLIENT="""+"TRUE"+""") AND");
SelectVacQuery.SQL.Add(" (E.ACTIVE_PROFESSION="""+"TRUE"+""") AND ");
SelectVacQuery.SQL.Add(" (C.ID=F.ID) AND (C.ID=P.ID) AND (S.ID=E.ID)");
If FAge Then SelectVacQuery.SQL.Add(" AND (C.AGE>=E.AGE_BEG) AND (C.AGE<=E.AGE_END)");
If FSalary Then SelectVacQuery.SQL.Add(" AND (C.SALARY<=E.SALARY)");
If FFormation Then SelectVacQuery.SQL.Add(" AND (F.FORMATION=E.FORMATION)");
If FProfession Then
Begin
SelectVacQuery.SQL.Add(" AND (P.PROFESSION=E.PROFESSION)");
If FCathegory Then SelectVacQuery.SQL.Add(" AND (P.CATHEGORY>=E.CATHEGORY)");
If FStag Then SelectVacQuery.SQL.Add(" AND (P.STAG>=E.STAG)");
End;
If Not FindAll Then
Begin
If FSub_name Then SelectVacQuery.SQL.Add(" AND (C.SUR_NAME="""+SUB_NAME+""")");
If FName Then SelectVacQuery.SQL.Add(" AND (C.NAME="""+NAME+""")");
If FSec_name Then SelectVacQuery.SQL.Add(" AND (C.SECOND_NAME="""+SEC_NAME+""")");
If FPseries Then SelectVacQuery.SQL.Add(" AND (C.PASSPORT_SERIES="""+PSERIES+""")");
If FPNumber Then SelectVacQuery.SQL.Add(" AND (C.PASSPORT_NUMBER="""+PNUMBER+""")");
End;
SelectVacQuery.SQL.Add(")");
SelectVacQuery.Open;
Когда я сдавал такое преподу он сказа, что это будет работать медленне чем уже скомпилиный запрос,
сильные будут ли тормоза?
Как ограничить кол-во выборки?
Есть ли другие варианты реализации такого фильтра?
Как пересортировать определенный столбец в уже сформированном результате запроса, предварительно выбрав его в DBGrid"e? (Например как в WinComander"e - Имя, тип, размер, дата)
и последний вопросик :)
есть запрос
select sum(summs)
from table1
в DBGrid сделал колонку, Д7 назвал выходную колонку SUMMA_1 и все работает, а на другой машине он назвал ее по другому и все пипец - ошибка! Как быть? Как задать этой калонке четкое несменяемое имя?
Спасибо всем у кого хватило терпения дочитать все это, может кто и пожет! С уважением, Lucky[ELF]!
← →
Anatoly Podgoretsky (2004-01-27 20:27) [1]AS name
← →
Lucky[ELF] (2004-01-27 20:32) [2]
> Anatoly Podgoretsky © (27.01.04 20:27) [1]
> AS name
Это по поводу
Select Sum(field1) as Summ1
- это сюда? Я правельно понял? Спасибо, обязательно попробую.
← →
kaif (2004-01-27 21:21) [3]Нифига медленнее он работать не будет. Твой препод глупость сказал. Ты на правильном пути. Запрос с конструируемым текстом - лучший способ фильтрации. Перед открытием запроса делается Prepare. По фиг - текст его из потока взят или руками создан. Вот при повторном том же самом запросе можно, сделав Prepare один раз якобы чуток выиграть. Но время, уходящее на Prepare настолько несоизмеримо со временем самого запроса и всяких Fetch, что говорить об этом любят те, кто с базами данных работал только в своем воображении. Считай, что Prepare мгновенный. Больше выиграешь, если заменишь всякие
SelectVacQuery.SQL.Add("SELECT C.ID, C.SUR_NAME, C.NAME, C.SECOND_NAME,");
SelectVacQuery.SQL.Add("C.AGE, C.ADRESS,");
SelectVacQuery.SQL.Add("C.PASSPORT_SERIES, C.PASSPORT_NUMBER,");
SelectVacQuery.SQL.Add("C.PASSPORT_ISSUED, C.PASSPORT_DATE,");
SelectVacQuery.SQL.Add("C.REG_DATE, C.SALARY,");
на более лаконичное:
SQL.Text :=
"SELECT C.ID, C.SUR_NAME, C.NAME, C.SECOND_NAME,"#13+
"C.AGE, C.ADRESS,"#13+
"C.PASSPORT_SERIES, C.PASSPORT_NUMBER,"#13+
"C.PASSPORT_ISSUED, C.PASSPORT_DATE,"#13+
"C.REG_DATE, C.SALARY,"#13+
и так далее...
← →
Lucky[ELF] (2004-01-27 22:11) [4]Хм, да действительно,
> SQL.Text :=
> "SELECT C.ID, C.SUR_NAME, C.NAME, C.SECOND_NAME,"#13+
> "C.AGE, C.ADRESS,"#13+
> "C.PASSPORT_SERIES, C.PASSPORT_NUMBER,"#13+
> "C.PASSPORT_ISSUED, C.PASSPORT_DATE,"#13+
> "C.REG_DATE, C.SALARY,"#13+
это точно лучше выглядет.
Да я впринципе если бы не нашел другого выхода, то все равно написал бы с динам. генерацией, просто малоли чего еще есть в ИБ, фишек то много, всех и не узнаешь.
Спасибо.
← →
kaif (2004-01-28 02:29) [5]
Как ограничить кол-во выборки?
Некоторые последние клоны Yaffil (а возможно и Firebird) имеют опции для SELECT, позволяющие выбирать не весь набор, а скажем, N первых записей.
Руководство пользователя Yaffil SQL Server
Ограничение результатов выборки FIRST/SKIP
Результат выборки может быть ограничен с использованием инструкций
FIRST/SKIP. При значении аргумента FIRST, равном 0, результат выборки пустое - множество , в отличие от Firebird, выбрасывающего исключение с сообщением о невер -
ном параметре.
← →
Deniz (2004-01-28 07:45) [6]>kaif © (28.01.04 02:29) [5]
>Некоторые последние клоны Yaffil (а возможно и Firebird)
и FB в том числе
>в отличие от Firebird, выбрасывающего исключение с сообщением о неверном параметре.
В FB1.5 RC8 этой проблемы нет(скорее всего и в ранних RC нет, но проверить не могу, нет их у меня)
>Lucky[ELF]
И на последок, таблицы лучше связывать по JOIN в секции FROM, но не в WHERE
← →
Lucky[ELF] (2004-01-28 19:43) [7]
> И на последок, таблицы лучше связывать по JOIN в секции
> FROM, но не в WHERE
А этот как? Дай пару примеров, если не сложно.
← →
kaif (2004-01-29 01:06) [8]/*внутреннее объединение (вернет все строки из TABLE_A и TABLE_B, для которых выполняется условие после ON)*/
SELECT A.FIELD2, B.FIELD2
FROM TABLE_A A
INNER JOIN TABLE_B B
ON A.FIELD1 = B.FIELD1;
/*внешнее объединение (вернет строки из TABLE_A даже, если нет соответствующих условию строк в TABLE_B. Второе поле будет NULL)*/
SELECT A.FIELD2, B.FIELD2
FROM TABLE_A A
LEFT OUTER JOIN TABLE_B B
ON A.FIELD1 = B.FIELD1;
← →
Lucky[ELF] (2004-01-29 18:59) [9]Спасибочки!
С миру по нитки, голому рубаха ...
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.032 c