Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.033 c
3-79611
Игорь М
2004-01-30 14:24
2004.02.25
В числовом поле, содержится дата...


14-80245
Layner
2004-02-06 10:32
2004.02.25
Досовские батники, спецы! Подскажите, как вытащить день, время


14-80174
ИМХО
2004-01-30 13:19
2004.02.25
Семь вопросов на засыпку для шахматистов


8-80037
Boris&Doris
2003-10-13 14:14
2004.02.25
Midi


1-79825
ShiFT
2004-02-11 10:03
2004.02.25
как выдрать, изменить и cохранить ресурсы из чужих Exe и Dll?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский