Newsgroup: it.comp.lang.visual-basic
Titolo: Query, si può? [Aggiornamento]

Eccomi ancora qui.
Dal vecchio post ho fatto delle modifiche al mio databse.
Ora la situazione è la seguente.
-> Tabella "Utenti": c'è dentro l'anagrafica delle persone e il campo 
primario è UserID.
-> Tabella "Attivita": contiene le entrate/uscite degli utenti. Il campo 
primario è ID; il campo UserID identifica gli utenti interessati.
-> Tabella "Rimborsi": contiene le tariffe (rimborsi orari) degli 
utenti. Le tariffe cambiano nel tempo. Ora però ogni tariffa ha una data 
di inizio ed una di fine (prima solo DataInizio).
Allora... l'utente PINCO PALLINO dal 1-Mar-2004 ha come rimborso orario 
1,18 €. Dal 5-Apr-2004 invece ha 3,00 €.
Quindi le tabelle Utenti/Rimborsi sono:
Utenti:
PINCO PALLINO (UserID=1)
TIZIO CAIO (UserID=2)
....
PAOLINO PAPERINO (UserID=n)
Rimborsi:
(UserID=1) DataInizio: 1-Mar-2004 DataFine: 4-Apr-2004 Rimborso: 1,18
(UserID=1) DataInizio: 5-Apr-2004 DataFine: (Null) Rimborso: 3,00
(UserID=2) DataInizio: xx-yyy-zzzz DataFine: hh-kk-wwww
e così via.
Io vorrei che, dato un giorno (es.: 25-Feb-2004), facendo più join, si 
possa ottenere una tabella con:
Cognome, Nome, OraEntrata, OraUscita, Rimborso di ogni utente presente a 
lavoro quel giorno.
Finora sono riuscito ad ottenere qualcosa, ma il problema è che il WHERE 
della query mi filtra Datainizio e DataFine dei rimborsi troncandomi 
così le persone che erano presenti a lavoro un certo giorno ma che non 
avevano un rimborso a quella data, perchè ovviamente la query me le scarta.
Ora... io vorrei poter visualizzare per un certo giorno tutte le persone 
presenti, e indicare con dei punti interrogativi i rimborsi delle 
persone presenti a lavoro ma senza rimborso per quel giorno.
Prima lo riuscivo a fare perchè avevo costruito una funzione separata 
che, dato il giorno di riferimento e l'UserID si collegava al DB alla 
ricerca della tariffa e mi restituiva -1 se non la trovava o, in caso di 
esito positivo, mi restituiva la tariffa stessa. Allora potevo stampare 
a schermo anche degli avvisi riguardo queste incongruenze (lavoro si, 
tariffa assente).
Come posso fare per ottenere come risultato della query una tabella 
completa con la tariffa NULLA per i giorni in cui la tariffa non è 
fissata? Thx in anticipo!
-- 
Rivolterò il mondo per trovarlo, e anche se andasse in Indocina uno dei 
nostri starà nascosto in una ciotola di riso pronto a sparargli nel culo.
(Pulp Fiction)


Va sempre più o meno bene la mia query dell'altro post, ma usando una LEFT
JOIN tra utenti e rimborsi.
(magari dai un occhio a cosa fa la LEFT JOIN così capisci meglio)
ciaociao

 (magari dai un occhio a cosa fa la LEFT JOIN così capisci meglio)
Io ho provato con questa Query:
SELECT RimborsoOrario, Cognome, Nome, Entrata, Uscita FROM (Attivita 
LEFT JOIN Utenti ON Utenti.UserID=Attivita.UserID) LEFT JOIN Rimborsi ON 
Rimborsi.UserID=Utenti.UserID WHERE DataInizio<=" & Data & " AND 
(DataFine>=" & Data & " OR DataFine Is Null) AND Data=" & Data & " ORDER 
BY Cognome ASC, Nome ASC
Dove DataInizio e DataFine indicano l'inizio e la fine dei vari rimborsi.
Data è una variabile STRING impostata a "#01-Apr-2004#".
C'è una persona che l'1 aprile ha un record in ATTIVITA ma i suoi 
rimborsi sono segnato con DataInizio = 2-apr-2004 e quindi quando stampo 
il risultato della query questa persona non c'è.
Dove sbaglio?


> Data è una variabile STRING impostata a "#01-Apr-2004#".
Aggiungo che, nella query, il campo Data è un campo della tabella 
Attivita che indica appunto il giorno in cui la persona è Entrata/uscita 
agli orari indicati...


 Dove sbaglio?
Si vede che non hai dato un occhio alla LEFT JOIN..... ;-)
la left restituisce TUTTI i record della tabella che sta a SINISTRA!
Quindi Attivita LEFT JOIN Utenti non può restituire gli utenti che non hanno
un legame in Attività. Devi scrivere Utenti LEFT JOIN Attivita.
In oltre quel formato di data....non mi piace molto
ciaociao

> Si vede che non hai dato un occhio alla LEFT JOIN..... ;-)
Infatti ora ho provato con un RIGHT JOIN (cambiando di posto alcune 
tabelle nella query senò VB si incazzava) ma le cose non sono cambiate...
La nuova QUERY è questa:
SELECT RimborsoOrario, Cognome, Nome, Entrata, Uscita FROM (Utenti RIGHT 
JOIN Rimborsi ON Utenti.UserID=Rimborsi.UserID) LEFT JOIN Attivita ON 
Utenti.UserID=Attivita.UserID WHERE DataInizio<=" & Data & " AND 
(DataFine>=" & Data & " OR DataFine Is Null) AND Data=" & Data & " ORDER 
BY Cognome ASC, Nome ASC
E mi manca sempre quella persona dall'elenco.
Però credo che il problema sia nel WHERE.
Infatti io scrivo "... WHERE DataInizio<=#01-Apr-2004#" AND 
(DataFine>=#01-APR-2004# OR DataFine Is Null) ..." e questo spezza le 
gambe a quel record perchè Rimborsi.DataInizio vale 02/04/2004 per 
quella persona.
Sarà questo?
Se si, come faccio?


 Se si, come faccio?
comunque il problema sta nelle JOIN, riprova! sarai più fortunato! ;-)))
ciaociao

 se usi la RIGHT. Tu invece hai fatto in entrambe i casi il contrario! :)
Ok ho provato scambiando di posto Utenti con Rimborsi nella parentesi, e 
lasciando il RIGHT, ma non è cambiato nulla.
Però sono sempre più convinto che il problema sta nella WHERE perchè 
limita il numero di RIMBORSI. Quella benedetta persona che non compare 
nell'elenco ha Rimborso.DataInizio=2 aprile 2004 mentre io dico di 
prendere tutti i rimborsi con DataInizio<=1 aprile 2004 e quella non 
rientra nella categoria.
Quindi?


 Quindi?
azz.. hai ragione. Scusa ma sono preso con le mie di query ed ero un po'
distratto! :-P
Effettivamente la where fa il suo lavoro.....
Allora aspetta che mi rileggo tutto piů tardi a casa, poi ti faccio sapere
;-)
ciaociao

 ;-)
Ok attendo ansioso (e intanto faccio dell'altro)...
Ti ringrazio infinit(esim)amente per l'aiuto :)


 Ti ringrazio infinit(esim)amente per l'aiuto :)
Effettivamente non mi viene in mente nulla per farlo con una unica SELECT...
e imho non è possibile.
Secondo me dovresti tenere una tabella temporanea con tutti i campi che ti
interessano, poi con 2 query hai risolto.
Prima inserisci tutti (e solo) gli utenti in questa tabella, poi fai una
update con la join su 'rimborsi' in modo da aggiornare gli altri campi in
base al filtro che ti interessa, e il gioco è fatto :)
spero di essere stato spiegato! ;-)
ciaociao

 base al filtro che ti interessa, e il gioco è fatto :)
Non ho capito molto bene...
Per tabella intendi proprio nel DB o intendi una tabella aperta da VB 
(ADODB.Recordset)?
E in che senso faccio una update?
Attendo fiducioso...


 Attendo fiducioso...
ciaociao

>Attendo fiducioso...
Ti farò sapere quanto prima :)
Intanto grazie :)
P.S.: Questa tabella di appoggio, non la si può creare virtualmente 
all'occorrenza?
Per virtualmente intendo sia in runtime in VB ma che non esiste davvero 
nel databse, o anche crearla in runtime nel DB ma cancellarla al termine 
dell'utilizzo...
Se dovessi creare tante tabelle di appoggio per ogni report che 
necessiti di una query inapplicabile sarebbe "brutto", ma magari crearle 
all'occorrenza sarebbe l'ideale...


 crearle all'occorrenza sarebbe l'ideale...
per creare tabelle vedi CREATE TABLE, per eliminarle DROP TABLE
ciaociao

> per creare tabelle vedi CREATE TABLE, per eliminarle DROP TABLE
Ok ti ringrazio.
Questa la proverò appena possibile...
Comunque ho aggirato un po' il mio problema.
per ora ti dico i risultati ottenuti con questa soluzione-tampone (che 
cesserà di essere tampone quando controllerò quanto sia veloce la 
soluzione della tabella in runtime).
Con il vecchio metodo di ricerca dei rimborsi, per ogni utente, per ogni 
giorno del report, un report dettagliato dal 22/03/2004 al 06/04/2004 ci 
impiegava 2,95 secondi per essere calcolato. Ora ne impiego 0,44.
Appena provo la tabella temporanea ti faccio sapere :)
