Query SQLServer

martedì 14 settembre 2010 - 15.01

dompa72 Profilo | Senior Member

ho questa tabella

Cod Data Valore
001 01/01/10 10
002 02/02/10 5
001 02/01/10 8
001 03/01/10 9
002 03/01/10 4
002 04/02/10 1

Devo fare una query che deve restituirmi il valore associato all'ultima data per codice
Cod Data Valore
001 03/01/10 9
002 04/02/10 1

per ottenere questo oggi faccio due query la prima: select Cod, Max(Data) as DataUltima group by Cod e la seconda (o meglio per ogni riga per risultato) cerco il valore per i dati corrispondenti al Cod e la Data

C'è un modo per avere il tutto con un unico risultato???, eventualmente sfruttando le sub-query?

Grazie


lbenaglia Profilo | Guru

>C'è un modo per avere il tutto con un unico risultato???, eventualmente
>sfruttando le sub-query?

Ciao,

Puoi ottenere quello che cerchi utilizzando una tabella derivata oppure una CTE.
Ti allego un esempio che sfrutta una CTE:

USE tempdb; CREATE TABLE dbo.foo( Cod char(3) NOT NULL, Data date NOT NULL, Valore tinyint NOT NULL ); INSERT dbo.foo VALUES('001', '20100101', 10); INSERT dbo.foo VALUES('002', '20100202', 5); INSERT dbo.foo VALUES('001', '20100102', 8); INSERT dbo.foo VALUES('001', '20100103', 9); INSERT dbo.foo VALUES('002', '20100103', 4); INSERT dbo.foo VALUES('002', '20100204', 1); WITH CTE_GetKey(Cod, Data) AS ( SELECT Cod, MAX(Data) FROM dbo.foo GROUP BY Cod ) SELECT F.* FROM dbo.foo AS F JOIN CTE_GetKey AS CTE ON F.Cod = CTE.Cod AND F.Data = CTE.Data ORDER BY F.Cod; /* Output: Cod Data Valore ---- ---------- ------ 001 2010-01-03 9 002 2010-02-04 1 (2 row(s) affected) */ DROP TABLE dbo.foo;

>Grazie
Prego.

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

boccia75 Profilo | Junior Member

Io farei in questo modo:
SELECT A.COD,A.DAT,A.VALORE
FROM TABELLA A WHERE A.DAT=(SELECT MAX(B.DAT)
FROM TABELLA B
WHERE A.COD=B.COD)

Ciao!

OPS non avevo visto la risposta precedente.

dompa72 Profilo | Senior Member

>Io farei in questo modo:
>SELECT A.COD,A.DAT,A.VALORE
>FROM TABELLA A WHERE A.DAT=(SELECT MAX(B.DAT)
>FROM TABELLA B
>WHERE A.COD=B.COD)
>
>Ciao!
>
>OPS non avevo visto la risposta precedente.

Questo va bene quando si lavora con due tabelle oppure il confronto viene fatto con un solo campo,
nel mio caso il confronto devo farlo con due campi.

Grazie lo stesso

dompa72 Profilo | Senior Member

>>C'è un modo per avere il tutto con un unico risultato???, eventualmente
>>sfruttando le sub-query?
>
>Ciao,
>
>Puoi ottenere quello che cerchi utilizzando una tabella derivata
>oppure una CTE.
>Ti allego un esempio che sfrutta una CTE:
>
>USE tempdb;
>
>CREATE TABLE dbo.foo(
>Cod char(3) NOT NULL,
>Data date NOT NULL,
>Valore tinyint NOT NULL
>);
>
>INSERT dbo.foo VALUES('001', '20100101', 10);
>INSERT dbo.foo VALUES('002', '20100202', 5);
>INSERT dbo.foo VALUES('001', '20100102', 8);
>INSERT dbo.foo VALUES('001', '20100103', 9);
>INSERT dbo.foo VALUES('002', '20100103', 4);
>INSERT dbo.foo VALUES('002', '20100204', 1);
>
>WITH CTE_GetKey(Cod, Data)
>AS
>(
> SELECT Cod, MAX(Data)
> FROM dbo.foo
> GROUP BY Cod
>)
>SELECT F.*
>FROM dbo.foo AS F
>JOIN CTE_GetKey AS CTE
>ON F.Cod = CTE.Cod
>AND F.Data = CTE.Data
>ORDER BY F.Cod;
>
>/* Output:
>
>Cod Data Valore
>---- ---------- ------
>001 2010-01-03 9
>002 2010-02-04 1
>
>(2 row(s) affected)
>
>*/
>
>DROP TABLE dbo.foo;
>
>>Grazie
>Prego.
>
>Ciao!
>--
>Lorenzo Benaglia
>Microsoft MVP - SQL Server
>http://blogs.dotnethell.it/lorenzo/

onestamente non conoscevo proprio Common Table Expressions, un ottimo metodo per le ricorsioni
fino a quando posso spingere questo CTE??


Grazie

lbenaglia Profilo | Guru

>onestamente non conoscevo proprio Common Table Expressions, un
>ottimo metodo per le ricorsioni
Si, esatto, le CTE possono essere utilizzate per scrivere query ricorsive (quella del mio esempio non lo è).

>fino a quando posso spingere questo CTE??
Di default una CTE ricorsiva gestisce al massimo 100 ricorsioni superate le quali genera un errore e la query viene interrotta.
Tramite l'hint MAXRECURSION puoi specificare un numero personalizzato di ricorsioni (da 0 a 32767).

>Grazie
Prego.

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

dompa72 Profilo | Senior Member

>>onestamente non conoscevo proprio Common Table Expressions, un
>>ottimo metodo per le ricorsioni
>Si, esatto, le CTE possono essere utilizzate per scrivere query
>ricorsive (quella del mio esempio non lo è).
Mi fai un esempio

>
>>fino a quando posso spingere questo CTE??
>Di default una CTE ricorsiva gestisce al massimo 100 ricorsioni
>superate le quali genera un errore e la query viene interrotta.
>Tramite l'hint MAXRECURSION puoi specificare un numero personalizzato
>di ricorsioni (da 0 a 32767).
>
>>Grazie
>Prego.
>
>Ciao!
>--
>Lorenzo Benaglia
>Microsoft MVP - SQL Server
>http://blogs.dotnethell.it/lorenzo/

grazie ancora

lbenaglia Profilo | Guru

>Mi fai un esempio
Leggi questo thread:
http://www.dotnethell.it/forum/messages.aspx?ThreadID=30644

>grazie ancora
Prego.

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

boccia75 Profilo | Junior Member

La query che ti ho postato funziona correttamente con l'esempio che hai fatto...
Il nome della tabella dalla quale estrarre i dati è TABELLA(scusa il gioco di parole), A e B sono due alias per la stessa tabella.
CIAO!

dompa72 Profilo | Senior Member

>La query che ti ho postato funziona correttamente con l'esempio
>che hai fatto...
>Il nome della tabella dalla quale estrarre i dati è TABELLA(scusa
>il gioco di parole), A e B sono due alias per la stessa tabella.
USE tempdb;

CREATE TABLE dbo.foo(
Cod char(3) NOT NULL,
Data datetime NOT NULL,
Valore tinyint NOT NULL
);

INSERT dbo.foo VALUES('001', '20100101', 10);
INSERT dbo.foo VALUES('002', '20100202', 5);
INSERT dbo.foo VALUES('001', '20100102', 8);
INSERT dbo.foo VALUES('001', '20100103', 9);
INSERT dbo.foo VALUES('002', '20100103', 4);
INSERT dbo.foo VALUES('002', '20100204', 1);

SELECT A.COD,A.DATA,A.VALORE
FROM dbo.foo A WHERE A.DATA = (SELECT MAX(B.DATA)
FROM dbo.foo B
WHERE A.COD=B.COD)

DROP TABLE dbo.foo;

ho provato e funziona

la differenza tra i due metodi????
>CIAO!
>
>
Grazie
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-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5