2010-10-29 15 views
5

Ho una tabella comeCome ottengo diversi valori più alti da una tabella?

id f1 
-------------- 
1 2000-01-01 
1 2001-01-01 
1 2002-01-01 
1 2003-01-01 

E voglio ottenere dire che le ultime 3 date in una fila

CREATE TABLE Test 
(
    id INT NOT NULL, 
    f1 DATETIME NOT NULL, 
) 

INSERT INTO Test (id, f1) VALUES (1, '1/1/2000') 
INSERT INTO Test (id, f1) VALUES (1, '1/1/2001') 
INSERT INTO Test (id, f1) VALUES (1, '1/1/2002') 
INSERT INTO Test (id, f1) VALUES (1, '1/1/2003') 

SELECT T1.* FROM Test as T1 

Stava cercando qualcosa di simile

  SELECT T1.*,T2.* 
      FROM Test AS T1 
LEFT OUTER JOIN Test AS T2 ON T1.id = T2.id AND (T2.f1 > T1.f1) 
+3

Perché deve essere tutto in una riga? Sarebbe molto più semplice avere solo una colonna. –

+1

Penso che abbia molto più senso restituirli come righe e non 1 riga con più colonne. – dotariel

+0

hai bisogno delle tre ultime date per ogni ID? (Ho notato che il tuo ID è sempre 1) –

risposta

3

in SQL Server si potrebbe fare select top 3 * from Test order by f1 desc. Altri DBMS sono posibilities simili come MySQL di limit, Oracle rownum ecc

+0

Questo non funzionerebbe. Questo darebbe le ultime 3 date in una colonna. Maestro1024 chiede le ultime 3 date in una riga. – pavanred

3

Anche se non sono Sicuramente come ottenerli in una singola riga, potresti iniziare con:

SELECT * FROM Test ORDER BY f1 DESC LIMIT 3 

Questo dovrebbe dare un risultato simile:

id f1 
1 2003-01-01 
1 2002-01-01 
1 2001-01-01 

metterle in una singola riga, però, può essere un po 'più difficile ...

2

È possibile farlo con una combinazione di ORDER BY, TOP e PIVOT, almeno su SQL Server. Sembra che molte delle altre risposte abbiano ignorato la necessità che il risultato fosse "tutto in una riga".

0

È possibile ottenere le prime 3 date di seguito ruotando la tabella e magari concatenando le date se le si desidera in una colonna dopo la rotazione.

Modifica: Questa è una query per ruotare la tabella e fornire le ultime 3 date di seguito. Ma per ruotare è necessario conoscere i dati disponibili nella tabella. Ho pensato che poiché stiamo interrogando per le ultime 3 date non sapremo le valli esatte per girare attorno alla colonna della data. Quindi, in primo luogo, ho interrogato le ultime 3 date in una tabella temporanea. Quindi ha eseguito un pivot sul numero_riga 1, 2 e 3 per ottenere le ultime 3 date di seguito.

Select Top 3 * into #Temp from Test order by f1 desc 

Ora, perno su colonna row_number -

SELECT id,[3] as Latest,[2] as LatestMinus1,[1] as LatestMinus2 
FROM (
select ROW_NUMBER() OVER(ORDER BY f1) AS RowId,f1,id from #Temp) AS Src 
PIVOT (Max(f1) FOR RowId IN ([1],[2],[3])) AS pvt 

Questo si traduce in -

Id | Latest     |LatestMinus1    |LatestMinus2 
1 | 2003-01-01 00:00:00.000 | 2002-01-01 00:00:00.000 | 2001-01-01 00:00:00.000 

E, naturalmente

drop table #Temp 
+0

Modifica: aggiunta una query alla mia risposta. – pavanred

+0

Gli analytics non sono supportati da tutti i database: SQL Server 2005+, Oracle 9i +, PostgreSQL 8.4 + ... ma non MySQL –

0

Che dire di questo?

SELECT T1.f1 as "date 1", T2.f1 as "date 2", T3.f1 as "date 3" 
    FROM (SELECT * 
     FROM `date_test` 
     ORDER BY `f1` DESC 
     LIMIT 1) AS T1, 
     (SELECT * 
     FROM `date_test` 
     ORDER BY `f1` DESC 
     LIMIT 1, 1) AS T2, 
     (SELECT * 
     FROM `date_test` 
     ORDER BY `f1` DESC 
     LIMIT 2, 1) AS T3 
; 

quali uscite:

+------------+------------+------------+ 
| date 1  | date 2  | date 3  | 
+------------+------------+------------+ 
| 2003-01-01 | 2002-01-01 | 2001-01-01 | 
+------------+------------+------------+ 

L'unico inconveniente è che avete bisogno di almeno tre file, altrimenti non restituirà nulla ...

Utilizzando JOIN, si può fare questo :

SELECT T1.id, 
     T1.f1 as "date 1", 
     T2.f1 as "date 2", 
     T3.f1 as "date 3" 
    FROM `date_test` as T1 
    LEFT JOIN (SELECT * FROM `date_test` ORDER BY `f1` DESC) as T2 ON (T1.id=T2.id AND T1.f1 != T2.f1) 
    LEFT JOIN (SELECT * FROM `date_test` ORDER BY `f1` DESC) as T3 ON (T1.id=T3.id AND T2.f1 != T3.f1 AND T1.f1 != T3.f1) 
GROUP BY T1.id 
ORDER BY T1.id ASC, T1.f1 DESC 

Che restituirà qualcosa del tipo:

+----+------------+------------+------------+ 
| id | date 1  | date 2  | date 3  | 
+----+------------+------------+------------+ 
| 1 | 2001-01-01 | 2003-01-01 | 2002-01-01 | 
+----+------------+------------+------------+ 

Lo svantaggio è che date1, date 2 e date 3 non sarà necessariamente in un ordine specifico (come da esempio di output sopra). Ma questo può essere raggiunto programmaticamente. Il lato positivo è che è possibile inserire una clausola WHERE prima del GROUP BY ed è possibile cercare per T1.id, ad esempio.

1

in T-SQL (Questo ti porterà le prime tre date, anche se sono tutti lo stesso valore)

with TestWithRowNums(f1, row_num) as 
(
select f1, row_number() over(order by [f1] desc) as row_num from test 
) 
select 
(select [f1] from TestWithRowNums where row_num = 1) as [Day 1], 
(select [f1] from TestWithRowNums where row_num = 2) as [Day 2], 
(select [f1] from TestWithRowNums where row_num = 3) as [Day 3] 

Questo ti porterà le prime tre date DISTINTI

with TestWithRankNums(f1, rank_num) as 
(
select f1, dense_rank() over(order by [f1] desc) as rank_num from test 
) 
select 
(select top 1 [f1] from TestWithRankNums where rank_num = 1) as [Day 1], 
(select top 1 [f1] from TestWithRankNums where rank_num = 2) as [Day 2], 
(select top 1 [f1] from TestWithRankNums where rank_num = 3) as [Day 3] 

Try questo in SQL Server 2005

--to get top three values even if they are the same 
select [1] as Day1, [2] as Day2, [3] as Day3 from 
(select top 3 f1, row_number() over(order by [f1] desc) as row_num from test) src 
pivot 
(
max(f1) for row_num in([1], [2], [3]) 
) as pvt 
--to get top three distinct values 
select [1] as Day1, [2] as Day2, [3] as Day3 from 
(select f1, dense_rank() over(order by [f1] desc) as row_num from test) src 
pivot 
(
max(f1) for row_num in([1], [2], [3]) 
) as pvt 
+0

Sto usando MS SQL e questo non funziona. La sintassi è corretta o non è valida su MS SQL? – Maestro1024

+0

@ Maestro1024, funziona solo sulle nuove versioni di SQl Server, ma sicuramente supera il controllo della sintassi. – HLGEM

+0

@ Maestro1024, quale versione di MS SQL Server stai usando? –

Problemi correlati