SQLServer2008R2 --- Selezionare ultimi 4 record in ordine Crescente

domenica 16 febbraio 2014 - 11.36
Tag Elenco Tags  SQL Server 2008 R2

renarig Profilo | Expert

Chiaramente con SQLServer sono un po "arrugginito" ( Non è che poi io sia mai stato brillante )

Di una tabella con un campo data devo selezionare le ultime 4 date
mettendole pero in ordine crescente.

Fino ad ora il meglio che sono riuscito a fare è :
SELECT TOP (100) PERCENT TaId, TaData, TaNote, TaNum FROM ( SELECT TOP (4) TaId, TaData, TaNote, TaNum FROM dbo.Tabe ORDER BY TaData DESC ) AS TTT ORDER BY TaData

Ma penso che ci siano delle soluzioni alternative e migliori.

Consigli ? Grazie

.

alx_81 Profilo | Guru

ciao
>Di una tabella con un campo data devo selezionare le ultime 4 date
>mettendole pero in ordine crescente.
le ultime quattro date prese una volta sola o gli ultimi quattro record?
Con quello che fai, la query interna ricava gli ultimi 4 record (con date più recenti) e poi le riordina in maniera crescente.
E direi che può andare. Ci sono altri modi, ma si basano su ranking functions, e credo che i piani potrebbero essere meno vantaggiosi rispetto a quelli che generi con quello che scrivi. La tabella è molto grande? Su quel campo data hai indici? Perché a lungo andare potrebbe diventare una query pesante..
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://blogs.dotnethell.it/suxstellino
http://suxstellino.wordpress.com
http://mvp.microsoft.com/profiles/Alessandro.Alpi

renarig Profilo | Expert

>le ultime quattro date prese una volta sola o gli ultimi quattro record?
Hai ragione non mi sono spiegato.
La data è indicizzata e non ammette duplicati quindi le ultime 4 date
corrispondono agli ultimi 4 record ed è quello che voglio

la tabella è molto piccola , potrà arrivare al masimo a 4000/5000 record


>E direi che può andare. Ci sono altri modi, ma si basano su ranking
>functions, e credo che i piani potrebbero essere meno vantaggiosi
Questo è quello che immaginavo ma di cui non ero sicuro

Grazie per la conferma
.

alx_81 Profilo | Guru

>Questo è quello che immaginavo ma di cui non ero sicuro
ti ho fatto un esempio così, giusto per farti vedere come potevi approcciare (a volte è un approccio efficace, ma in questo caso, se guardi i piani IMHO è meglio la soluzione di cui parlavamo prima):


USE tempdb; GO CREATE TABLE #tempDate ( TaId int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED , TaData date CONSTRAINT UK_TaData UNIQUE , TaNote varchar(200) , TaNum int ); GO INSERT INTO #tempDate (TaData, TaNote, TaNum) VALUES ('20140101', '', 1), ('20140102', '', 2), ('20140103', '', 3), ('20140104', '', 4), ('20140105', '', 5), ('20140106', '', 6), ('20140107', '', 7), ('20140108', '', 8); GO DECLARE @NumeroDiRecord int = 4; WITH wDate AS ( SELECT TaId , TaData , TaNote , TaNum , rnum = ROW_NUMBER() OVER(ORDER BY TaData DESC) FROM #tempDate TD ) SELECT TaId , TaData , TaNote , TaNum FROM wDate WHERE rnum <= @NumeroDiRecord ORDER BY TaData; DROP TABLE #tempDate; GO
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://blogs.dotnethell.it/suxstellino
http://suxstellino.wordpress.com
http://mvp.microsoft.com/profiles/Alessandro.Alpi

renarig Profilo | Expert

Wooww !!!! Mi hai spalancato un mondo con il "WITH ..... AS "
Si tratta di una Vista in effetti inesistente ma che diventa base di lancio per altre viste ....

a questo punto se mi permetti vorrei riuscire a fare un doppio WITH che poi servira a lanciare una terza vista

Qualcosa piu o meno cosi. ma mi va in errore !!! e non capisco perche ??
USE tempdb; GO CREATE TABLE #tempDate ( TaId int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED , TaNote varchar(200) , TaNum int ); GO INSERT INTO #tempDate (TaNote, TaNum) VALUES ('abc', 10), ('dfg', 20); GO WITH wDate1 AS (SELECT TaId, TaNote, TaNum FROM #tempDate TD1) -- Penso che l'errore sia sul WITH che sta qui sotto <<--------------------- WITH wDate2 AS (SELECT TaId, TaNote, TaNum FROM #tempDate TD2) SELECT TaId, TaNote, TaNum FROM wDate1 UNION ALL SELECT TaId, TaNote, TaNum FROM wDate2 DROP TABLE #tempDate; GO

Chiaramente la query non ha nessun significato pratico, è solo un test per i 2 WITH

Grazie
.

alx_81 Profilo | Guru

>Si tratta di una Vista in effetti inesistente ma che diventa
>base di lancio per altre viste ....
eh no, purtroppo è una Common Table Expression e non una vista. Ragion per cui, by design, può essere chiamata solo dopo che è stata definita.


>Qualcosa piu o meno cosi. ma mi va in errore !!! e non capisco perche ??
come detto prima, va fatta e consumata.. è solo una sorta di "contenitore" che può essere usato poi nella query immediatamente successiva, e non di più.
Per fare ciò che serve a te puoi fare due @table, strumento che avevi già da prima delle WITH.
Le CTE sono utilissime per utilizzare le ranking function e per la ritorsione (per quello sono proprio molto comode).
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://blogs.dotnethell.it/suxstellino
http://suxstellino.wordpress.com
http://mvp.microsoft.com/profiles/Alessandro.Alpi
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