Newsgroup: it.comp.lang.visual-basic
Titolo: Query, forse raggruppamento?

Raga è sabato, lo so, e sono le 12.
Ma nessuno ha idea di come risolvere 'sta query:
Ho due tabelle:
TEMP
CODICE |   DATA   | Importo
---------------------------
  XXX   | 01/05/04 | NULL
  YYY   | 05/05/04 | NULL
  XXX   | 14/05/04 | NULL
  ZXZ   | 16/05/04 | NULL
e la tabella Tariffe:
CODICE | DataInizio |  DataFine  | Importo
------------------------------------------
  XXX   | 01/03/2004 | 13/05/2004 |  1,00 €
  XXX   | 14/05/2004 |       NULL |  1,30 €
  YYY   | 01/01/2004 |       NULL |  4,00 €
  ZXZ   | 01/01/2004 |       NULL |  8,50 €
Allora il mio problema è aggiornare TEMP settando il campo Importo, 
prendendolo dalla tabella Tariffe e joinando col campo Codice.
Per ogni record della tabella TEMP va presa la tariffa con il range di 
data giusto.
Ad es. il primo record di Temp deve avere Importo=1,00 €, perchè 
Temp.Data rientra in quei range della tabella tariffe, mentre il terzo 
record di Temp deve avere Importo=1,30 €.
Quando in Tariffe DataFine = Null vuol dire che ancora non è prevista 
una scadenza per quella tariffa (diciamo che temporalmente è l'ultima 
arrivata e quindi attualmente in uso).
Però ovviamente per record vecchi bisogna associare le vecchie tariffe 
(se ci sono, altrimenti restano NULL).
Avevo fatto questo:
UPDATE Temp T LEFT JOIN Tariffe TAR
ON T.Codice=TAR.Codice
SET T.Importo=TAR.Importo
WHERE TAR.DataInizio<=T.Data AND
   (TAR.DataFine>=T.Data OR TAR.DataFine IS NULL)
ma non mi fa aggiornare nulla, l'errore è:
ERRORE DI SINTASSI NELL'OPERAZIONE UPDATE
Vi ringrazio anticipatamente!
-- 
Quando noi ignoranti eravamo di più,
tutto era più bello...
(Adriano Celentano)

 ha scritto nel messaggio
news:40d40e05$2...@x-privat.org...

Ciao,
che database stai usando ?
Con Access non da errore anche se ovviamente non aggiorna come da te voluto.
TAR.DataInizio è sempre <= di T.Data quindi Aggiorna i record che hanno
TAR.DataFine=Null oppure Tar.DataFine>=T.Data.
Risultato: tutti i record vengono aggiornati.
io la farei così
-------------------------
UPDATE Temp T LEFT JOIN Tariffe TAR
ON T.Codice=TAR.Codice
SET T.Importo=TAR.Importo
WHERE T.Data BETWEEN TAR.DataInizio
     AND Iif(IsNull(TAR.Datafine),Tar.DataInizio,TAR.DataFine)
-------------------------
ma a quanto pare il problema è la sintassi SQL che per il tuo Db non è
corretta.
Ciao Giorgio

 TAR.DataFine=Null oppure Tar.DataFine>=T.Data.
Si infatti mi venivano duplicati i record.
Ho provato in modo diverso e *pare* che funzioni, ma devo fare controlli 
+ approfonditi:
UPDATE Temp T LEFT JOIN Tariffe Tar
ON T.Codice=Tar.Codice AND
Tar.DataInizio<=T.Data AND
(Tar.DataFine>=T.Data OR Tar.DataFine IS NULL)
SET T.Importo=Tar.Importo
Però, ripeto, devo controllare moooooooolto meglio, ma ad una prima 
analizi mi funzionava tutto.
P.S.: Uso Access2000
-- 
Quando noi ignoranti eravamo di più,
tutto era più bello...
(A. Celentano)


Ciao,
l'aver spostato la logica nella ON della LEFT JOIN non cambia assolutamente
nulla, un'espressione booleana rimane sempre un'espressione booleana. La
tabella Temp con i dati del tuo esempio viene aggiornata in tutte le sue
righe.
Ciao Giorgio

 righe.
Si ma l'espressione booleana:
Tariffe.DataInizio<=Temp.Data AND
  (Tariffe.DataFine>=Temp.Data OR Tariffe.DataFine IS NULL)
con le mie tabelle di esempio di prima, dovrebbe associarmi in modo 
corretto (cioè secondo quello che voglio io) i record 1 e 3.
Prendiamo ad esempio il primo record di Temp, con Data=01/05/2004
Facendo il join con Tariffe ottengo, associato a questo record, due 
record della tabella tariffe, ma di questi solo uno deve essere scelto 
perchè solo uno corrisponde al vero:
1) 1/3/2004<=1/5/2004 AND (13/5/2004>=1/5/2004 OR 13/5/2004 is null)
e questo è vero, quindi il primo record di tariffe mi passa il controllo.
2) 14/5/2004<=1/5/2004 AND (...) ma già qui è falso.
Però se questo controllo lo metto nel WHERE mi avviene la duplicazione, 
se invece lo metto nell'ON tutto è ok...


 se invece lo metto nell'ON tutto č ok...
No bugia ho mentito!!!
Ho provato a mettere l'espressione anche nel WHERE e mi funziona!
Forse a lavoro l'ho scritta male... Poi riscrivendola giusta dopo averla 
spostata nell'ON e vedendo il risultato giusto sono giunto a conclusioni 
sbarellate.
Scusate il thread inutile...
-- 
Quando noi ignoranti eravamo di piů,
tutto era piů bello...
(A. Celentano)


ma hai provato con i dati che hai postato ?
          Tar.Datainizio   T.Data
--------------------------------
XXX 01/03/2004 <= 01/05/04
XXX 14/05/2004 <=14/05/04
ZXZ   01/01/2004 <=16/05/04
YYY  01/01/2004 <=05/05/04
--------------------------------
sembra evidente no ? Basta provarla con i dati che hai fornito (io lo ho
fatto)
poi se a te va bene va bene a tutti.
Ciao Giorgio

 fatto)
Si ma forse hai dimenticato che il mio controllo č del tipo:
CONDIZIONE1 AND CONDIZIONE2
A me non basta che Tar.DataInizio<=T.Data, come hai mostrato qui sopra.
Io scelgo Tar.DataInizio<=T.Data *AND* (Tar.DataFine>=T.Data OR 
Tar.DataFine IS NULL)
      Tar.Datainizio Tar.DataFine
  -------------------------------
  XXX 01/03/2004     14/05/2004
  XXX 14/05/2004        NULL
  ZXZ 01/01/2004        NULL
  YYY 01/01/2004        NULL
  -------------------------------
-- 



esatto, quindi per tutte le date di Tar.DataFine a NULL la condizione č
VERA!!!!!
Provare per credere.
Ciao Giorgio

 Ciao Giorgio
Si ma ho fatto un JOIN col campo codice quindi ogni record ti Temp si 
confronta SOLO cone le tariffe relative a QUEL prodotto.
Quindi Nella tabella Temp, i record con codice XXX si confronteranno 
*solo* con i record della tabella Tar aventi Codice=XXX.
O ti era sfuggito?


 O ti era sfuggito?
assolutamente No!
Questi sono i tuoi dati
TEMP
CODICE |   DATA   | Importo
---------------------------
  XXX   | 01/05/04 | NULL
  YYY   | 05/05/04 | NULL
  XXX   | 14/05/04 | NULL
  ZXZ   | 16/05/04 | NULL
e la tabella Tariffe:
CODICE | DataInizio |  DataFine  | Importo
------------------------------------------
  XXX   | 01/03/2004 | 13/05/2004 |  1,00 ?
  XXX   | 14/05/2004 |       NULL |  1,30 ?
  YYY   | 01/01/2004 |       NULL |  4,00 ?
  ZXZ   | 01/01/2004 |       NULL |  8,50 ?
Questa č la tua WHERE
--------------
TAR.DataInizio<=T.Data AND   (TAR.DataFine>=T.Data OR TAR.DataFine IS NULL)
--------------
Sostituiamo i campi con i valori tenendo in considerazione il join e vediamo
tutte le condizioni che si verificano VERE
------------------------
XXX  01/03/2004<=01/05/04 AND  (13/05/2004>=01/05/04 OR 13/05/2004 IS NULL)
XXX  14/05/2004<=14/05/04 AND  (NULL>=01/05/04 OR NULL IS NULL)
ZXZ   01/01/2004<=16/05/04 AND  (NULL>=16/05/04 OR NULL IS NULL)
YYY  01/01/2004<=05/05/04 AND (NULL>=05/05/04 OR NULL IS NULL)
------------------------
non so piů come spiegartelo, se anche di fronte all'evidenza e alla prova
empirica non riesco a convincerti getto la spugna.
Ciao Giorgio

 nel messaggio news:NXeBc.7669$GQ3.1...@twister2.libero.it...
ops, la seconda riga di XXX č cosě
-----------
XXX  14/05/2004<=14/05/04 AND  (NULL>=14/05/04 OR NULL IS NULL)
----------
ma non cambia nulla


Quindi non vedo questa duplicazione di dati. Mi pare che i risultati 
ottenuti siano corretti...



Una query di aggiornamento non duplica i dati, il fatto č che in base alle
condizioni aggiorna tutti i record di Temp e non solo la prima e la terza
riga. Ma se il risultato va bene cosě abbiamo discusso di Niente.
Ciao Giorgio

 riga. Ma se il risultato va bene cosě abbiamo discusso di Niente.
ma infatti io volevo aggiornare *tutti* i campi, non solo il primo e il 
terzo record :D
Quei due li ho tirati in ballo per fare un esempio su alcune voci che 
avevano piů di una tariffa...
Cmq grazie lo stesso x l'aiuto ;)
