1 (edited by memult 2016-05-31 10:41:34)

Topic: Условие поиска WHERE

Добрый день,подскажите,как правильно использовать в SQL запросе, после WHERE значения из мультикомбобокса?
Например в конкретном запросе:

SQLQuery('SELECT count(Формулировка),Percent.Проценты,Изменение,Tema.Тема,Aktive.Активность,users.login FROM employees LEFT OUTER JOIN Tema ON Tema.id=employees.id_Tema LEFT OUTER JOIN Percent ON Percent.id=employees.id_percent LEFT OUTER JOIN users ON users.id=employees.id_users LEFT OUTER JOIN Aktive ON Aktive.id=employees.id_Aktive WHERE '+
             'date(Изменение) NOT BETWEEN ('+Stats.DateFromDvizh.sqlDate+') AND date('+Stats.DateToDvizh.sqlDate+') AND '+
             'Aktive.Активность="Да" AND Percent.Проценты <> "100%"  Tema.id='+Stats.cb1.sqlValue+' GROUP BY login', Results);

Где Stats.cb1 - нужный комбобокс

Re: Условие поиска WHERE

Помогите пожалуйста с запросом, не получается подставить именно мультикомбобокс, с обычным комбобоксом работает нормально.

Re: Условие поиска WHERE

Пример скрипта:

procedure Form1_Button1_OnClick (Sender: string; var Cancel: boolean);
var
    Results: TDataSet;
    sSQL: string;
    i: integer;
begin
    if Form1.cbGroups.SelectedCount=0 then
    begin
        ShowMessage('You should select at least one item.');
        Exit;
    end;

    sSQL := 'SELECT lastname FROM employees WHERE';


    for i := 0 to Form1.cbGroups.Items.Count-1 do
    begin
        if Form1.cbGroups.ItemsChecked[i] then
            sSQL := sSQL + ' id_groups='+IntToStr(Form1.cbGroups.dbIndexToID(i))+' OR';
    end;
    SetLength(sSQL, Length(sSQL)-3);



    SQLQuery(sSQL, Results);
    Form1.Memo1.Clear;

    while not Results.Eof do
    begin
        Form1.Memo1.Lines.Add( Results.FieldByName('lastname').asString );
        Results.Next;
    end;

end;


Также можете скачать проект с данным примером:

Post's attachments

Attachment icon ComboBox MultiSelect in SQL query.zip 9.94 kb, 439 downloads since 2016-06-01 

Dmitry.

Re: Условие поиска WHERE

Спасибо за помощь.

Re: Условие поиска WHERE

Добрый день, подскажите пожалуйста, как быть если таких мультикомбобоксов два и более? Пробовал через вложенный цикл, не получилось.

Re: Условие поиска WHERE

memult wrote:

Добрый день, подскажите пожалуйста, как быть если таких мультикомбобоксов два и более? Пробовал через вложенный цикл, не получилось.

Приветствую,


Сделал для вас пример:

Post's attachments

Attachment icon ComboBoxes MultiSelect in SQL query.zip 10.88 kb, 592 downloads since 2016-08-22 

Dmitry.

Re: Условие поиска WHERE

Спасибо за пример, но работает это некорректно.
Когда стоит условие сразу в двух мультикомбобоксах, результат отображается неверно.
К примеру выборка для вашего примера: Groups: Home,Sport;  Sex: Female
Результат: Ivanov,John,Elizabet,Lara. А должен быть: Lara. Два условия сразу не соблюдаются.

Re: Условие поиска WHERE

memult wrote:

Спасибо за пример, но работает это некорректно.
Когда стоит условие сразу в двух мультикомбобоксах, результат отображается неверно.
К примеру выборка для вашего примера: Groups: Home,Sport;  Sex: Female
Результат: Ivanov,John,Elizabet,Lara. А должен быть: Lara. Два условия сразу не соблюдаются.

вам необходимо немного другая логика работы, попробуй так

procedure Form1_Button5_OnClick (Sender: string; var Cancel: boolean);
var
    Results: TDataSet;
    sSQL1, sSQL2, sSQL: string;
    i: integer;
begin
    sSQL := 'SELECT id, lastname FROM employees';


    sSQL1 := '';
    for i := 0 to Form1.cbGroups.Items.Count-1 do
    begin
        if Form1.cbGroups.ItemsChecked[i] then
            sSQL1 := sSQL1 + ' id_groups='+IntToStr(Form1.cbGroups.dbIndexToID(i))+' OR';
    end;

    if sSQL1<>'' then
    begin
        SetLength(sSQL1, Length(sSQL1)-3);
        sSQL1 := '(' + sSQL1 + ')';
    end;



    sSQL2 := '';
    for i := 0 to Form1.cbSex.Items.Count-1 do
    begin
        if Form1.cbSex.ItemsChecked[i] then
            sSQL2 := sSQL2 + ' id_sex='+IntToStr(Form1.cbSex.dbIndexToID(i))+' OR';
    end;

    if sSQL2<>'' then
    begin
        SetLength(sSQL2, Length(sSQL2)-3);
        sSQL2 := '(' + sSQL2 + ')';
    end;



    if (sSQL1<>'') or (sSQL2<>'') then  sSQL := sSQL +  ' WHERE ';
    if (sSQL1<>'') and (sSQL2<>'') then sSQL := sSQL + sSQL1 + ' AND '+ sSQL2
    else sSQL := sSQL + sSQL1 + sSQL2;


    Form1.TableGrid1.dbSQL:=sSQL; // the id field, want to be able to edit or delete the entry from the table component
    Form1.TableGrid1.dbGeneralTable := 'employees'; // Optional (in the case of complex SQL queries with sub queries, you need to choose the main table of the database, also it need to be able to edit or delete the entry from the table component)
    Form1.TableGrid1.dbListFieldsNames :='delete_col,Lastname'; // If you do not want to see the value of the id in the component table, enter a name for the column delete_col
    Form1.TableGrid1.dbSQLExecute;

end;
Dmitry.

Re: Условие поиска WHERE

Спасибо, для данного примера все работает как нужно.
Но не совсем понятен этот участок кода:

 if (sSQL1<>'') or (sSQL2<>'') then  sSQL := sSQL +  ' WHERE ';
    if (sSQL1<>'') and (sSQL2<>'') then sSQL := sSQL + sSQL1 + ' AND '+ sSQL2
    else sSQL := sSQL + sSQL1 + sSQL2;

Просто у меня таких мультикомбобоксов 7.. Не могли бы Вы пояснить как изменится этот участок кода, если увеличиваем количество мультикомбобоксов.

Re: Условие поиска WHERE

memult
Написал универсальную процедуру, для поиска по любому количеству кобобоксов

procedure SearchByComboBoxes (ComboBoxes: Array of TdbComboBox; Grid: TdbStringGridEx);
var
    Results: TDataSet;
    sSQL: string;
    sWhere: string;
    s: string;
    i,c: integer;
    ComboBox: TdbComboBox;
begin
    sSQL := 'SELECT id, lastname FROM employees';
    sWhere := '';
    
    c := Length(ComboBoxes)-1;
    for i := 0 to c do
    begin
        ComboBox := ComboBoxes[i];

        s := '';
        for i := 0 to ComboBox.Items.Count-1 do
        begin
            if ComboBox.ItemsChecked[i] then
                s := s + ' '+ComboBox.dbForeignKeyShort+'='+IntToStr(ComboBox.dbIndexToID(i))+' OR';
        end;

        if s<>'' then
        begin
            SetLength(s, Length(s)-3);
            s := '(' + s + ')';
            if sWhere<>'' then sWhere := sWhere + ' AND ';
            sWhere := sWhere + s;
        end;
    end;

    if sWhere<>'' then sSQL := sSQL + ' WHERE ' + sWhere;

    Grid.dbSQL:=sSQL; // the id field, want to be able to edit or delete the entry from the table component
    Grid.dbGeneralTable := 'employees'; // Optional (in the case of complex SQL queries with sub queries, you need to choose the main table of the database, also it need to be able to edit or delete the entry from the table component)
    Grid.dbListFieldsNames :='delete_col,Lastname'; // If you do not want to see the value of the id in the component table, enter a name for the column delete_col
    Grid.dbSQLExecute;
end;


Для использования данной процедуры, необходимо передать ей массив ComboBox-ов и компонент грида, куда необходимо вывести результат, пример использования:

procedure Form1_Button8_OnClick (Sender: string; var Cancel: boolean);
begin
    SearchByComboBoxes( [Form1.cbGroups, Form1.cbSex, Form1.ComboBox1] , Form1.TableGrid1)
end;
Dmitry.

11 (edited by memult 2016-09-01 10:43:43)

Re: Условие поиска WHERE

А вывести сразу в отчет не получится? Т.е перечислить эти комбобоксы сразу в процедуре и передать результат SQL в отчет.

Сейчас смог реализовать только для 5 комбобоксов, по Вашему первому варианту. 30 комбинаций..

Re: Условие поиска WHERE

memult wrote:

А вывести сразу в отчет не получится? Т.е перечислить эти комбобоксы сразу в процедуре и передать результат SQL в отчет.

Сейчас смог реализовать только для 5 комбобоксов, по Вашему первому варианту. 30 комбинаций..

В принципе да, разместите на форме кнопку с действием Отчет (SQL), ее можно также сделать невидимой.
затем в коде измените

    Grid.dbSQL:=sSQL; // the id field, want to be able to edit or delete the entry from the table component
    Grid.dbGeneralTable := 'employees'; // Optional (in the case of complex SQL queries with sub queries, you need to choose the main table of the database, also it need to be able to edit or delete the entry from the table component)
    Grid.dbListFieldsNames :='delete_col,Lastname'; // If you do not want to see the value of the id in the component table, enter a name for the column delete_col
    Grid.dbSQLExecute;

на

    Form1.Button9.dbSQL := sSQL;
    Form1.Button9.Click;
Dmitry.

Re: Условие поиска WHERE

Вроде все получилось, спасибо за помощь.