SELECT campo di record che dipende dal MAX

giovedì 22 aprile 2010 - 11.30

Klaus-zanini Profilo | Senior Member

Ciao a tutti,
forse mi sto perdendo in un bicchiere d'acqua...avrei bisogno di estrapolare una SELECT che mi restituisca un campo dello stesso record di un altro che è il massimo per quella tabella.
Mi spiego meglio:

TABELLA
IDMagazzino IDArticolo IDMovimento
A01 Art001 1
A02 Art001 2
A03 Art001 3

Obiettivo mio è fare una select che mi dice qual è l'ultimo IDMagazzino in cui è stato messo l'articolo Art001 considerando IDMovimento massimo come ultimo. Io lo riesco a fare solo con una doppia select...SELECT IDMagazzino FROM TABELLA WHERE IDMovimento = (SELECT MAX(IDMovimento) FROM TABELLA WHERE IDArticolo='Art001').
Ma non mi pare molto performante...

Qualcuno ha altre idee?

dinoxet Profilo | Senior Member

prova così :

SELECT IDMagazzino, MAX(IDMovimento) as maxidmov FROM TABELLA WHERE IDArticolo='Art001'

i tink...
DINOXET
__________________________________________
impossible is only a word

Klaus-zanini Profilo | Senior Member

non funziona perché mi chiede che IDMagazzino sia nella clausola di group by e mettendolo lì dentro mi mostra ovviamente 3 record...

dinoxet Profilo | Senior Member

SELECT IDMagazzino, MAX(IDMovimento) as maxidmov FROM TABELLA WHERE IDArticolo='Art001' group by idmagazzino

ha ragione quando si inseriscono formule valgono per tutti i campi in questione.



DINOXET
__________________________________________
impossible is only a word

Klaus-zanini Profilo | Senior Member

Infatti, ma il problema permane...

mettendolo in group by mi mostra tutta la tabella perché IDMagazzino è distinto per ogni riga

dinoxet Profilo | Senior Member

SELECT last(IDMagazzino) as ultimomag, MAX(IDMovimento) as maxidmov FROM TABELLA WHERE IDArticolo='Art001'

prova così



DINOXET
__________________________________________
impossible is only a word

trappy Profilo | Newbie

non basta che fai "SELECT TOP 1 FROM TABELLA WHERE IDARTICOLO=.... ORDER BY IDMOVIMENTO DESC" ?

Klaus-zanini Profilo | Senior Member

>SELECT last(IDMagazzino) as ultimomag, MAX(IDMovimento) as maxidmov
>FROM TABELLA WHERE IDArticolo='Art001'
>
>prova così


Che sintassi è? ho provato ma mi da questo errore:

Messaggio 195, livello 15, stato 10, riga 3
'LAST' non è un valore riconosciuto di nome di funzione predefinita.

Klaus-zanini Profilo | Senior Member

>non basta che fai "SELECT TOP 1 FROM TABELLA WHERE IDARTICOLO=....
>ORDER BY IDMOVIMENTO DESC" ?

Non va bene perché l'esempio che ho fatto è di 3 righe con lo stesso articolo, ma io ho bisogno di una query che faccia il group by sull'articolo. Il TOP 1 mi restituisce un solo record, io ne voglio 1 per articolo.

lbenaglia Profilo | Guru

>Obiettivo mio è fare una select che mi dice qual è l'ultimo IDMagazzino
>in cui è stato messo l'articolo Art001 considerando IDMovimento
>massimo come ultimo.

Ciao Claudio,

Una idea potrebbe essere quella di ordinare il result set in modo discendente per IDMovimenti e di considerare la prima riga:

USE tempdb; CREATE TABLE dbo.foo( IDMagazzino char(3) NOT NULL, IDArticolo varchar(10) NOT NULL, IDMovimento int NOT NULL ); INSERT dbo.foo VALUES ('A01', 'Art001', 1) , ('A02', 'Art001', 2) , ('A03', 'Art001', 3); SELECT TOP 1 IDMagazzino FROM dbo.foo WHERE IDArticolo = 'Art001' ORDER BY IDMovimento DESC; /* Output: IDMagazzino ----------- A03 (1 row(s) affected) */ DROP TABLE dbo.foo;

Se l'esempio non si addice al tuo problema ti invito a postare tutto il codice necessario a riprodurre il risultato che vuoi ottenere.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lbenaglia Profilo | Guru

>>non basta che fai "SELECT TOP 1 FROM TABELLA WHERE IDARTICOLO=....
>>ORDER BY IDMOVIMENTO DESC" ?
>
>Non va bene perché l'esempio che ho fatto è di 3 righe con lo
>stesso articolo, ma io ho bisogno di una query che faccia il
>group by sull'articolo. Il TOP 1 mi restituisce un solo record,
>io ne voglio 1 per articolo.

Ecco non avevo letto fino in fondo.
Il risultato che vuoi ottenere non potrai mai ottenerlo con una unica query, ma dovrai basarti su una CTE o su una tabella derivata.
Questo è un esempio basato sul precedente che ho postato:

USE tempdb; CREATE TABLE dbo.foo( IDMagazzino char(3) NOT NULL, IDArticolo varchar(10) NOT NULL, IDMovimento int NOT NULL ); INSERT dbo.foo VALUES ('A01', 'Art001', 1) , ('A02', 'Art001', 2) , ('A03', 'Art001', 3) , ('A02', 'Art002', 1) , ('A05', 'Art003', 1) , ('A01', 'Art003', 2); WITH CTE_GetKey (IDArticolo, IDMovimento) AS ( SELECT IDArticolo, MAX(IDMovimento) FROM dbo.foo GROUP BY IDArticolo ) SELECT F.IDMagazzino, F.IDArticolo FROM dbo.foo AS F JOIN CTE_GetKey AS CTE ON F.IDArticolo = CTE.IDArticolo AND F.IDMovimento = CTE.IDMovimento ORDER BY F.IDArticolo; /* Output: IDMagazzino IDArticolo ----------- ---------- A03 Art001 A02 Art002 A01 Art003 (3 row(s) affected) */ DROP TABLE dbo.foo;

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Klaus-zanini Profilo | Senior Member

eh...immaginavo non si potesse, ma ci speravo

Provo a vedere se la tua soluzione è più performante. Grazie mille
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5