Newsgroup: it.comp.appl.access
Titolo: Periodi consecutivi

Di seguito indico una query SQL che ho trovano su internet
Qualcuno è in grado di tradurla in Query Access.
credo che sia proprio quello di cui ho bisogno per selezionare periodo consecutivi:
ritengo che td1 e td2 siano sempre la stessa tabella (spero!!)
 
 
select td1.StartDate, 
 
       td2.EndDate, 
 
       datediff(d, td1.StartDate, td2.EndDate) as Days
 
from #tempDates td1 left join
 
     #tempDates td2 on td1.Id <> td2.Id
 
where (td2.StartDate = DateAdd(d, 1, td1.EndDate)) OR (td2.StartDate = DateAdd(d, 0, td1.EndDate))

please, help me!

singer laid this down on his screen :

Per definire 2 periodi consecutivi occorrono 4 date:
in quale tabella e in quali campi si trovano?
 
Possono aversi anche più di 2 periodi in tabella,
fra i quali rilevare la consecuzione?
 
Bruno

Grazie per l'attenzione innanzitutto!!
Qualche post dietro avevo posto la questione in altri termini e questa è la soluzione che avevo trovato (forse un po' macchinosa):
 
SELECT A.*, DateDiff("d",[A.DAL],[
A.AL
]+1) AS DIFF 
 
FROM Assenze AS A INNER JOIN Assenze AS B ON A.DAL = 
B.AL
+1 
WHERE A.CIP = B.CIP AND A.Id <> B.Id 
ORDER BY a.cip and a.dal; 
 
UNION SELECT A.*, DateDiff("d",[A.DAL],[
A.AL
]+1) AS DIFF 
FROM Assenze AS A INNER JOIN Assenze AS B ON 
A.AL
=B.DAL-1 
WHERE A.CIP = B.CIP AND A.Id <> B.Id; 
 
 
qui c'è la tabella (Assenze) e i due campi data: DAL e AL
 
SI POSSONO ESSERE ANCHE Più DI DUE PERIORI FRA I QUALI RILEVARE LA SEQUENZA
 
GRAZIE

 SI POSSONO ESSERE ANCHE Più DI DUE PERIORI FRA I QUALI RILEVARE LA SEQUENZA
Risposta per me non esauriente.
Non posso indovinare la struttura della tabella.
 
Bruno

Tabella Assenze (legata dal lato molti con l'anagrafica del personale, ma questo non credo sia fondamentale).
La tabella ha i seguenti campi
ID
CIP (CHIAVE PRIMARIA, che è la matricola del personale che lega la tabella al lato uno)
tipo assenza
DAL (data iniziale periodo di assenza)
AL (Data finale periodo di assenza)
Questa è la struttura.
 
In questa tabella ci sono 18000 record
 
io ho bisogno di controllare tutti i periodi consecutivi di uno stesso CIP
contare i giorni tra la data iniziale (del periodo) e la data finale (del periodo consecutivo e verificare quando questi sono maggiori di 60 giorni

 periodi consecutivi
 
Questa che ho inventato al volo funziona egregiamente
(beh ... almeno  se ho  capito la tua esigenza) ed e' 
semplicissima :  
 
SELECT A.dal_, B.al_, (B.al_ - A.dal_) AS giorni_
FROM T AS A, T AS B
WHERE A.al_ +1 = B.dal_;
 
Dove T e' la tua tabella.
 
Ti acchiappa sistematicamente tutti i periodi consecutivi
e  te  li  schiaffa  in modo tale che in DAL c'e' la data 
inizio del periodo e in AL c'e' la data fine dell' ultimo
periodo consecutivo all' iniziale. 
 
In terza colonna ti riporta la durata in giorni dei 
periodi consecutivi.
 
 
 
Fammi sapere

ci siamo quasi.
ma se i periodi consecutivi sono tre li divide. ti faccio l'esempio specifico:
 
18.11.2008 20.11.2008
21.11.2008 26.11.2008
27.11.2008 09.12.2008
 
la query restituisce:
 
18.11.2008 26.11.2008 8gg
21.11.2008 09.12.2008 18 gg
 
 
io devo avere 
18.11.2008 09.12.2008
 
un altro piccolo sforzo, ti prego


Ok ... mumble mumble ... :-) 
 
Sai programmare in VB sotto access ? Se si il problema si 
puo' risolvere cosi' : 
 
esegui la query su T, salvi i risultati in una tabella
temporanea T1.
Riesegui la stessa query sulla temporanea T1 e salvi
i risultati in T2 
 
Se n. records di T1 = n. records di T2 allora fine e
osservi T2. 
 
Altrimenti ripeti il procedimento 
 
Mi sono spiegato ? 
 
 

ti sei spiegato, ma non sono in grado di tradurre tutto questo in VBA.

 ti sei spiegato, ma non sono in grado di tradurre tutto questo in VBA.
 
Mannaggia mi dispiace ... Vorrei aiutarti ma credo  che con una
sola query non si possa fare quello che serve a te. Il problema
ha natura tipicamente ricorsiva in  quanto non  e' noto  quanti 
periodi consecutivi possa avere  un dipendente, per cui nemmeno 
con una subquery se ne esce. 
 
Spero di sbagliarmi. Vediamo se qualcuno piu' bravo risolve.
 

grazie, comunque,
è un pò di giorni che pongo questo quesito qui, ma ho visto che è stato glissato,
speravo nell'aiuto di Karl!
 
 
ciao

scusami, 
ma la query di unione che ho postato io funziona e dà il risultato che cerco
non puoi analizzarla e trovare solo l'ultimo passaggio che mi serve
avrei bisogno di aggiungere in struttura un criterio per selezionare i periodi maggiori di 60 giorni
solo che con la query di unione non si entra in struttura

singer explained :

Ho preso una strada troppo lunga ma stasera
ci riguardo e conto di accorciarla un po'...
=============================
Private Sub Command62_Click()
Dim db As Database, RS_Cip As Recordset, SQL As String
Dim RS_Assenze As Recordset, j As Long, k As Long
Dim dateDAL() As Date, dateAL() As Date
 
Set db = CurrentDb
SQL = "SELECT Assenze.CIP FROM Assenze GROUP BY Assenze.CIP;"
Set RS_Cip = db.OpenRecordset(SQL)
 
Do Until RS_Cip.EOF
    SQL = "SELECT Assenze.CIP, Assenze.Dal, Assenze.Al FROM Assenze "
    SQL = SQL & "WHERE (((Assenze.CIP) = '" & RS_Cip![CIP] & "')) ORDER 
BY Assenze.Dal;"
    Set RS_Assenze = db.OpenRecordset(SQL)
 
    k = 1
    ReDim dateDAL(1 To k)
    ReDim dateAL(1 To k)
    dateDAL(k) = RS_Assenze![Dal]
    dateAL(k) = RS_Assenze![Al]
 
    RS_Assenze.MoveNext
    Do Until RS_Assenze.EOF
        If RS_Assenze![Dal] = DateAdd("d", 1, dateAL(k)) Then
            dateAL(k) = RS_Assenze![Al]
        Else
            k = k + 1
            ReDim Preserve dateDAL(1 To k)
            ReDim Preserve dateAL(1 To k)
            dateDAL(k) = RS_Assenze![Dal]
            dateAL(k) = RS_Assenze![Al]
        End If
        RS_Assenze.MoveNext
    Loop
 
    For j = 1 To UBound(dateDAL)
        If DateDiff("d", dateDAL(j), dateAL(j)) + 1 >= 60 Then
            MsgBox RS_Cip![CIP] & vbCrLf & dateDAL(j) & "   " & 
dateAL(j) & _
                vbCrLf & DateDiff("d", dateDAL(j), dateAL(j)) + 1
        End If
    Next
    RS_Cip.MoveNext
Loop
 
End Sub
=====================================
 
Bruno

GraZie, appena sono a un pc la provo immediatamente



Non so se è chiedere troppo. Ma visto che ci devi ancora lavorare :-) , non è possibile.ottenere un output editabile tipo una query, una tabella, un file Excel. Così vedo che restituisce un messaggio a video.
GraZie

 Excel. Così vedo che restituisce un messaggio a video. GraZie
 
Te lo sai fare un piatto di spaghetti con due uova fritte
o muori di fame se non hai il cuoco?
 
La tabella Assenze60 ha gli stessi campi della tabella Assenze,
con l'aggiunta di un campo GG, long.
 
=======================================
Private Sub Command62_Click()
Dim db As Database, RS_Cip As Recordset, SQL As String
Dim RS_Assenze As Recordset, j As Long, k As Long
Dim dateDAL() As Date, dateAL() As Date, ID
Dim RS_Target As Recordset
 
Set db = CurrentDb
SQL = "SELECT Assenze.CIP FROM Assenze GROUP BY Assenze.CIP;"
Set RS_Cip = db.OpenRecordset(SQL)
Set RS_Target = db.OpenRecordset("Assenze60")
 
Do Until RS_Cip.EOF
    SQL = "SELECT Assenze.ID, Assenze.CIP, Assenze.Dal, Assenze.Al FROM 
Assenze "
    SQL = SQL & "WHERE (((Assenze.CIP) = '" & RS_Cip![CIP] & "')) ORDER 
BY Assenze.Dal;"
    Set RS_Assenze = db.OpenRecordset(SQL)
 
    k = 1: ID = RS_Assenze![ID]
    ReDim dateDAL(1 To k)
    ReDim dateAL(1 To k)
    dateDAL(k) = RS_Assenze![DAL]
    dateAL(k) = RS_Assenze![AL]
 
    RS_Assenze.MoveNext
    Do Until RS_Assenze.EOF
        If RS_Assenze![DAL] = DateAdd("d", 1, dateAL(k)) Then
            dateAL(k) = RS_Assenze![AL]
        Else
            k = k + 1
            ReDim Preserve dateDAL(1 To k)
            ReDim Preserve dateAL(1 To k)
            dateDAL(k) = RS_Assenze![DAL]
            dateAL(k) = RS_Assenze![AL]
        End If
        RS_Assenze.MoveNext
    Loop
 
    For j = 1 To UBound(dateDAL)
        If DateDiff("d", dateDAL(j), dateAL(j)) + 1 >= 60 Then
            'MsgBox ID & vbTab & RS_Cip![CIP] & vbCrLf & dateDAL(j) & " 
  " & dateAL(j) & _
                vbCrLf & DateDiff("d", dateDAL(j), dateAL(j)) + 1
            With RS_Target
                .AddNew
                ![ID] = ID
                ![CIP] = RS_Cip![CIP]
                ![DAL] = dateDAL(j)
                ![AL] = dateAL(j)
                ![GG] = DateDiff("d", dateDAL(j), dateAL(j)) + 1
                .Update
            End With
        End If
    Next
    RS_Cip.MoveNext
Loop
 
End Sub
====================================
 
Bruno

FA_VO_LO_SO!!
Io non so come fate....
Sono commosso.
 
A proposito, non sono bravo in cucina :-)
 
e la tabella è decisamente più vicina alle mie esigenze.
Naturalmente il controllo lo devo ripetere nel tempo e questa SUB mi aggiunge i record ogni volta.
Allora ho pensato. Senti Senti!
 
Faccio partire una macro che lancia una query di eliminazione sulla tabella Assenze60 e poi faccio partire la sub.
 
Ho hai una soluzione già bella e pronta (a proposito di uova fritte!!)
 
ciao e grazie, grazie, grazie ancora

singer formulated the question :

Dopo il
Set db = CurrentDB
 
aggiungi la riga:
db.Execute "DELETE Assenze60.* FROM Assenze60;"
 
Bruno

Perdonami, ma potrebbe esserci qualcosa che non va?
 
ho lanciato la prima volta la Sub e mi ha generato 26 periodi consecutivi.
Ho provato ad aggiungere dei periodi di assenza consecutiva alla mia tabella e la Sub non me li trova.
Se invece ne cancello qualcuno di quelli che già erano inseriti, allora scompaiono dopo la Sub
 
??

Incredibile!
 
Se io importo da un altro db replica l'intera tabella Assenze
la sub mi trova anche gli ulteriori record
ma se inserisco i nuovi periodi di assenza nel db (e lo faccio da una maschera), lancio la Sub e non succede niente: i nuovi periodi di assenza superiori a 60 giorni non vengono conteggiati.
Ma come è possibile!!!

dai, non lasciamo le cose a metà!

 dai, non lasciamo le cose a metà!
 
Non per fare lo smargiasso ma il problema e' classicamente ed 
elegantemente ricorsivo. 
 
per ogni persona fisica :
 
chiama la funzione :  
f()
 prendi il primo periodo (dalla tabella periodi) (da;a) e cerca 
 il consecutivo (da'=a+1;a')
 
 se lo trovi, poni (da;a) = (da;a') 
 chiama f() (chiamata dentro la f() stessa)
 
 Altrimenti restituisci  (da;a) e aggiungilo come record alla 
 tabella periodi_consecutivi
 esci da f() 
 
Osserva la compattezza e la chiarezza dello pseudo codice.
 

 dai, non lasciamo le cose a metà!
 
Guarda che io non lascio le cose a metà
Ho provato e riprovato e a casa mia (Win 8.1/Access 2013/64bit)
la procedura funziona correttamente, come tu stesso hai potuto
rilevare in qualche circostanza.
 
Per saperne di più dovrei avere sottomano il tuo file
con l'indicazione delle tue condizioni di lavoro e
delle circostanze nelle quali rilevi il malfunzionamento.
 
Se vuoi puoi inviarmi il tutto a 
brun...@libero.it
 
 
Bruno