Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: petrusic - Giugno 27, 2022, 07:30:22 pm

Titolo: [RISOLTO] query SQLite3 per importi assunti in valore assoluto
Inserito da: petrusic - Giugno 27, 2022, 07:30:22 pm
Oggi ho costruito una query SQLite per estrarre da una tabella del mio DB tutti record con la colonna Importi contenuti, in valore assoluto fra 20 e 30 €.

Come faccio sempre, prima di mandare in esecuzione il programma, ho eseguito la query in DBBrowse e, con mia sorpresa ho riscontrato l'estrazione di tutti i record con importi positivi.
Ho fatto la controprova, inserendo nella formula il segno "-". Questa volta sono stati estratti, sempre con l'opzione "abs", soltanto i record con importi negativi.

A questo punto mi sono deciso a provare il programma e, naturalmente, anche il programma ha risposto nella stessa maniera.

Quindi, in definitiva, le istruzioni funzionano, quello che non funziona è, secondo le mie attuali conoscenze, la gestione dell'opzione "abs"

Riporto, per completezza, la Select che poi ho dato in pasto al programma:
Codice: [Seleziona]
sql:= 'SELECT movimgg.CoVocMovvgg AS coVoMovg, movimgg.DtCoMovgg AS dtContMov, movimgg.DescrMovvgg AS causale, movimgg.ImpMovvgg AS Importo, movimgg.MonMovvgg AS lirEur, ';
        sql:= sql + 'piancont.NumVoce AS coVoPianCont, piancont.NomeVoce AS nmVocePianCont, piancont.ContrPartSiNo AS flgCtoColleg  FROM movimgg, piancont WHERE coVoMovg = coVoPianCont ';
        sql:= sql + ' AND dtContMov >= ' +  dataIni + ' AND dtContMov <= ' + dataFin + ' AND Importo >= ' + FloatToStr(abs(impMin)) + ' AND Importo <= ' + FloatToStr(abs(impMax));
        sql:= sql + ' ORDER BY Importo, dtContMov, movimgg.DtSolMovgg, movimgg.OraSolMovgg';
        swOpenErro:= OpenDbQuery1F1(sql);
        if swOpenErro then
        begin
          ShowMessage('*** RICERCA PER IMPORTO ***' + LineEnding + LineEnding + 'OPEN di ContabFamDB NON riuscita' + LineEnding + '(sql= "' + sql + '")' + LineEnding + LineEnding + 'Il Programma verrà chiuso');
          Halt;
        end
        else begin
          Form1.ZReadOnlyQuery1.First;
          while not Form1.ZReadOnlyQuery1.EOF do
          begin
            nuVoceCorr:= Form1.ZReadOnlyQuery1.FieldByName('coVoMovg').AsString;
            descr:= Form1.ZReadOnlyQuery1.FieldByName('causale').AsString;
            impMov:= Form1.ZReadOnlyQuery1.FieldByName('Importo').AsString;
            dataMov:= Form1.ZReadOnlyQuery1.FieldByName('dtContMov').AsString + chr(9);
            numPro:= numPro + 1;
            WriteLn(inttoStr(numPro) + ' - impMov= "' + impMov + '" | dataMov= "' + dataMov + '" | coVoMovg= "' + nuVoceCorr + '" | causale= "' + descr + '"');
            Form1.ZReadOnlyQuery1.Next;
          end;
        end;
        Form1.ZReadOnlyQuery1.Close;   

Non ci sono errori formali, ma il mio proposito è di estrarre con una sola query tutti i record con importo compreso fra: -30 e -20, nonchè quelli con importo compreso fra 20 e 30.

In base a quanto riscontrato, sono costretto ad eseguire 2 query, distinte, considerando separatamente le due fasce di importo.

C'é qualcosa che dovrei sapere e che non so?
 ??? :-\


Titolo: Re:query SQLite3 per importi assunti in valore assoluto
Inserito da: DragoRosso - Giugno 28, 2022, 01:29:56 am
E' tardi e magari dico stupidaggini, ma non puoi usare un paio di parentesi e duplicare (una con il + e una con il -) la parte riguardante l'importo mettendoci un OR tra le due clausole ?

Tipo:

Codice: [Seleziona]
AND ((Importo >= ' + FloatToStr(abs(impMin)) + ' AND Importo <= ' + FloatToStr(abs(impMax)))+ ' OR (Importo >= ' + FloatToStr(abs(impMin)*-1) + ' AND Importo <= ' + FloatToStr(abs(impMax)*-1)))

Ciao
Titolo: Re:query SQLite3 per importi assunti in valore assoluto
Inserito da: xinyiman - Giugno 28, 2022, 08:38:56 am
Oppure puoi usare una union e gestire il set di dati con qualcosa di simile a:

select 1 tipo, campo1 from tabella where campo1 between -20 and -30
union all
select 2 tipo, campo1 from tabella where campo1 between 20 and 30

Così quando scorri il recordset giochi con il campo tipo.
La funzione abs = absolute che io sappia rende positivo qualsiasi valore negativo
abs(20) = 20
abs(-20) = 20

Spero di essere stato d'aiuto
Titolo: Re:query SQLite3 per importi assunti in valore assoluto
Inserito da: nomorelogic - Giugno 28, 2022, 09:21:15 am
ciao
il problema è che la funzione abs(), nella clausola where, la devi applicare anche al campo "Importo" della tabella e non solo all'espressione di confronto ( mi riferisco a FloatToStr(abs(impMin)) ).


quindi devi scrivere:
Codice: [Seleziona]
...
AND abs(Importo) >= ' + FloatToStr(abs(impMin)) + ' AND abs(Importo) <= ' + FloatToStr(abs(impMax));
...
Titolo: Re:query SQLite3 per importi assunti in valore assoluto
Inserito da: petrusic - Giugno 28, 2022, 02:55:59 pm
ciao
il problema è che la funzione abs(), nella clausola where, la devi applicare anche al campo "Importo" della tabella e non solo all'espressione di confronto ( mi riferisco a FloatToStr(abs(impMin)) ).
quindi devi scrivere:
Codice: [Seleziona]
...
AND abs(Importo) >= ' + FloatToStr(abs(impMin)) + ' AND abs(Importo) <= ' + FloatToStr(abs(impMax));
...

Ho provato come mi hai detto tu e come mi ha detto DragoRosso.
Funzionano tutte e due.

La possibilità di utilizzare la funzione abs mi permette di rimanere aderente alla mia idea iniziale.

Grazie a tutti per le vostre illuminazioni.
 :D