Query access per intervallo date con parametri

di il
27 risposte

Query access per intervallo date con parametri

Buongiorno a tutti. Sto provando senza successo a definire una query per ottenere il numero di giorno trascorsi fra due date che recupero da una tabella così strutturata:
ID_Registrazioni : key
...altri campi non ssignificativi
DataIn : data
DataOUT : data
DatIn e DataOut sono riferiti ad una persona che fa ingresso\uscita da una sede. La query che dovrei scrivere, in buona sostanza deve recuperare le presenze delle persona fra un intervallo di date. Quello che ho fatto fin'ora funziona solo se le date che inserisco come parametri sono riferite allo stesso mese...
SELECT TBL_Registrazioni.ID_Anagrafica, Switch(DataIN<=[Data Dal] And DataOUT>[Data Al],DateDiff("d",[Data Dal],[Data Al])+1,DataIN<=#6/1/2022# And DataOUT=#6/30/2022#,DateDiff("d",#6/1/2022#,DataOUT+1),DataIN>#6/1/2022# And DataOUT<=#6/30/2022#,DateDiff("d",DataIN,DataOUT+1),DataIN>#6/1/2022# And DataOUT>#6/30/2022#,DateDiff("d",DataIN,#6/30/2022#)+1) AS Giorni
FROM TBL_Registrazioni;

27 Risposte

  • Re: Query access per intervallo date con parametri

    Può sembrare sbagliato a prima vista ma è così
    DataIN<DT_A and dataOUT<DT_DA
    sempre se ho capito cosa vuoi fare, cioè capire se in un determinato periodo (DT_DA->DT_A) la persona era "dentro"
  • Re: Query access per intervallo date con parametri

    Non ho capito la tua risposta ma grazie....vedo di spiegarmi meglio. In tabella ho la seguente riga:
    ID_REgistrazioni:1, ID_Anagrafica:1;ID_Sede:1;DataIn:03/01/2022;DataOut:15/01/2022
    ID_REgistrazioni:2, ID_Anagrafica:1;ID_Sede:2;DataIn:16/01/2022;DataOut:15/02/2022
    Ora la mia query, se inserisco ad esempio DataIn(01/01/2002) e DataOut(31/01/2022), dovrebbe restituirmi qualcosa tipo:
    ID_REgistrazioni:1, ID_Anagrafica:1;ID_Sede:1;Giorni:12
    ID_REgistrazioni:2, ID_Anagrafica:1;ID_Sede:2;Giorni:15
  • Re: Query access per intervallo date con parametri

    Ah ok, non vuoi sapere chi era "dentro" ma per quanti gg, scusa allora avevo capito/letto male
    ok quello che ti ho scritto lo puoi tenere come filtro per discriminare chi ha almeno un gg all'interno del periodo per cui calcolare e nel conto dei gg puoi mettere
    
    iif(dataOUT>DT_AL;DT_AL;dataOUT)-iif(DataIN<[DT_DAL];DT_DAL;DataIn)
    
    poi ci sarebbe bisogno di capire se il risultato 0 lo vuoi 1
    ad esempio se uno è "dentro" dal 15/01 al 01/02 e tu analizzi febbraio risulta presente dal 01/02 al 01/02 quindi viene 0
    ma anche se è "dentro" dal 15/01 al 02/02 e tu analizzi sempre febbraio risulta presente dal 01/02 al 02/02 quindi viene 1
    dipende cosa vuoi calcolare, potresti semplicemente fare +1 ma potrebbe nn aver senso.
    Ad esempio in ambito di ricovero ospedaliero l'entrata coincidente con l'uscita viene contata 1 gg di degenza esattamente come l'entrata con uscita il gg dopo.
  • Re: Query access per intervallo date con parametri

    Allora funziona solo se le date che inserisco come parametro sono relative allo stesso mese.

    Ad esempio, questa registrazione,
    ID_REgistrazioni:2, ID_Anagrafica:1;ID_Sede:2;DataIn:16/01/2022;DataOut:15/02/2022
    se inserisco 01/01/2022 e 3/01/2022 mi da errore...
  • Re: Query access per intervallo date con parametri

    Mi sembra vada bene ...
    prova a postare il tuo SQL finale ed un esempio di record per i quali dici che dà errore
  • Re: Query access per intervallo date con parametri

    Allora ,grazie per la pazienza...stavo provando a sistemare un pò con poca fortuna. Il codice SQL è questo:
    SELECT TBL_Registrazioni.ID_Anagrafica, IIf([DataIN]<[Data_dal],[Data_dal],[DataIN])-IIf([dataOUT]>[Data_al],[Data_al],[dataOUT]) AS Espr1
    FROM TBL_Registrazioni;
    Tralasciando che dove funziona ho un risultato negativo, i record nel db sono quelli sopra:
    ID_REgistrazioni:1, ID_Anagrafica:1;ID_Sede:1;DataIn:03/01/2022;DataOut:15/01/2022
    ID_REgistrazioni:2, ID_Anagrafica:1;ID_Sede:2;DataIn:16/01/2022;DataOut:15/02/2022
    Quello che mi aspetto io,inserendo 01/01/2022 e 31/01/2022 è:
    ID_REgistrazioni:1, ID_Anagrafica:1;ID_Sede:1;Giorni:12
    ID_REgistrazioni:2, ID_Anagrafica:1;ID_Sede:2;Giorni:15
    Invece dal momento che la seconda riga sfora il mese, ho un errore.
  • Re: Query access per intervallo date con parametri

    jotric ha scritto:


    Tralasciando che dove funziona ho un risultato negativo, i record nel db sono quelli sopra:
    diciamo che puoi migliorare anche a copiare visto che io nn ti ho scritto così ... poi scusa ma se ti viene negativo nn pensi magari di avere invertito i termini della sottrazione? (che giusto per ... si chiamano minuendo e sottraendo)
    continuando non capisco perchè dovrebbe darti errore, l'unica cosa è che tu abbia dei NULL probabilmente ma questo non mi sembra possibile dal tuo primo post. Così non fosse vanno aggiunti controlli di presenza (in realtà bastano degli "NZ" )

    EDIT: guarda non avevo molti dubbi ma ho provato a simulare la tua situazione e direi che quello che ti ho suggerito (e hai seguito male) funziona quindi ... hai dei NULL nei campi DataIN e/o DataOUT? come inserisci i valori di confronto Data_DAL e Data_AL ?
  • Re: Query access per intervallo date con parametri

    Si, hai ragione, ho invertito gli operandi. ma stavo solo provando a vedere se riuscivo a capirci qualcosa (come avrai capito non sono molto pratico di access ). Detto questo, in effetti ho dei campi vuoti, ma sono ad indicare che la persona non è ancora uscita da quella sede.
    Questi sono i dati su cui sto facendo le prove:
    • ID_REG ID_Anagrafica ID_Sede DataIN DataOUT
      1 1 1 03/01/2022 15/01/2022
      2 1 2 16/01/2022 15/02/2022
      3 1 1 21/08/2022 10/10/2022
      4 1 2 11/10/2022
    Ora inserendo gennaio come riferimento di ricerca (01/01/2022 - 31/01/2022)DT_DAL, DT_AL vorrei ottenere :
    • ID_Anagrafica ID_Sede Giorni
      1 1 12
      1 2 15
    Ora inserendo questo codice SLQ:
    
    SELECT TBL_Registrazioni.ID_Anagrafica, IIf([dataOUT]>[DT_AL],[DT_AL],[dataOUT])-IIf([DataIN]<[DT_DAL],[DT_DAL],[DataIn]) AS Espr1
    FROM TBL_Registrazioni;
    
    Il risultato che ho nel primo valore è giustamente 12, mentre la seconda riga restituisce #Errore
  • Re: Query access per intervallo date con parametri

    Ti assicuro che quello che ti ho proposto funziona, l'ho provato
    l'unica correzione da fare è gestire i NULL
    non hai risposto a questa:
    come inserisci i Data_DAL / Data_AL ? da dove li recuperi?
    (ti anticipo che la risposta corretta è da 2 controlli con "formato" data in una form)

    EDIT: oltretutto manca il filtro che ti avevo suggerito al primo post per considerare SOLO le righe interessate
  • Re: Query access per intervallo date con parametri

    Innanzi tutto grazie per la pazienza. I due campi DT_AL / DT_DAL sono parametri di immissione, quando eseguo la query mi chiede i limiti di ricerca ed io scrivo 31/01/2022 e 01/01/2022. Ora il null non l'ho gestito anche perchè nelle prime due righe della tabella, non dovrei avere il problema, sono compilati tutti i campi. Ora ho aggiunto il filtro, ma il risultato non cambia.
    
    SELECT TBL_Registrazioni.ID_Anagrafica, IIf([dataOUT]>[DT_AL],[DT_AL],[dataOUT])-IIf([DataIN]<[DT_DAL],[DT_DAL],[DataIn]) AS Espr1
    FROM TBL_Registrazioni
    WHERE (("DataIN"<"DT_DAL" And "dataOUT"<"DT_AL"));
    
  • Re: Query access per intervallo date con parametri

    Prova a formattare le date in formato europeo. Se non specifichi bene il formato, certe versioni di access, soprattutto le più datate fanno di testa loro creando questi problemi ,sopratutto sui calcoli.
  • Re: Query access per intervallo date con parametri

    Uso Office 365 e la data è formattata come "Data in cifre"
  • Re: Query access per intervallo date con parametri

    Era quello che temevo
    il modo giusto è quello di avere 2 controlli DAL AL in una form e passare quelli nell'SQL o meglio ancora creare "al volo" l'SQL inserendo i valori da vba
    proseguendo ...
    non ti accorgi che questa tua
    
    ...
    WHERE (("DataIN"<"DT_DAL" And "dataOUT"<"DT_AL"));
    
    ha qualcosa che non va? oltre al fatto che di nuovo hai preso il mio suggerimento e l'hai copiato sbagliato invertendo un < con un > e sbagliato anche il confronto con DAL AL

    detta tutta stai manifestando un mix di assenza di conoscenze di base, distrazione e sufficienza che diventa difficile aiutarti
  • Re: Query access per intervallo date con parametri

    Ci sono anche le queries Parametriche... "queste sconosciute"... da non confondere con il passaggio del Criterio...
    I Parametri sono oggetti...

    In modo Visuale si definiscono i Parametri dal Menù, in alto a DX si trova l'Icona [Parametri] nell'ultima TAB del Ribbon.
    
    PARAMETERS start Date, end Date;
    SELECT T1.*
    FROM T1
    WHERE (((T1.ID) Between [start] And [end]));
    Questa Query va valorizzata da codice...!
    Sub paramTest()
        Dim rs As DAO.Recordset	
        Dim qdf As DAO.QueryDef
        Set qdf = CurrentDb.QueryDefs("TuaQuery")
        qdf!start = Me!DataInizio
        qdf!end = Me!DataFine
        set rs=qdf.OpenRecordset
        Set qdf = Nothing
        ' Ora con il RS si può fare quello che si vuole anche assegnarlo ad una Form o ListBox...
    End Sub
    Ovviamente se si vule gestire una ACTION Query, non si aprirà il recordset ma si userà il Metodo EXECUTE di QueryDef.

    Per i più attenti... la grande differenza è che nella costruzione delle Query OnTheFly serve convertire la data in Accezione anglosassone, cosa che mi pare abbiate dimenticato tutti sopra...
    
    Dim sSQL As String
    sSQL="SELECT T1.* FROM T1"
    sSQL= sSQL & "WHERE (((T1.ID) Between " & clng([Forms!NomeForm!start]) & " And " & clng([Form!NomeForm!end])));
    Usare clng(Data) equivale a convertire in formato anglosassone con Format(TuaData,"mm/dd/yyyy"), tagliando il TIME, se si vuole il TIME serve convertire in DOUBLE ed instrodurre la conversione del decimale in relazione alle impostazioni del sistema usando:
    
    Str(cDbl(TuaData))
    Questo non risulta necessario se si usa la risoluzione IMPLICITA del motore...[Code] SELECT T1.* FROM T1 WHERE (((T1.ID) Between [Forms!NomeForm!start] And [Form!NomeForm!end])); Verificare se, usando i PARAMETERS serve la conversione facendo qualche considerazione....
Devi accedere o registrarti per scrivere nel forum
27 risposte