2015-12-24 12 views
6

Ho una tabella:Come trovare il valore successivo all'interno di una tabella in base a determinati criteri

ID | Name | Date 
1 | ABC | 2015-01-01 
2 | XYZ | 2015-01-02 
3 | ABC | 2015-01-03 
4 | ABC | 2015-01-04 

Voglio interrogare questa tabella modo tale che il risultato diventa:

ID | Name | Date  | NextDate 
1 | ABC | 2015-01-01 | 2015-01-03 
2 | XYZ | 2015-01-02 | null 
3 | ABC | 2015-01-03 | 2015-01-04 
4 | ABC | 2015-01-04 | null 

One la soluzione è:

select t1.*, 
    (select min(t2.Date) from TAB t2 where t2.ID > t1.ID t2.Name = t1.Name) NextDate 
from TAB t1 

Ma questo è molto lento come stiamo facendo l'aggregazione su ogni riga. C'è una soluzione alternativa a questo che è più efficiente di quanto sopra?

+2

Ogni possibilità di aggiornare il proprio SQL Server 2008 per 2012 o più recente? La funzione ['lead'] (https://msdn.microsoft.com/en-us/library/hh213125.aspx) sembra adattarsi esattamente al tuo conto. – Mureinik

risposta

3

Poiché SQL SERVER 2008 non supporta la funzione finestra LEAD, è necessario simularlo utilizzando row_number e self join. Prova questo

;WITH cte 
    AS (SELECT t1.*, 
       Row_number() 
        OVER(
        partition BY Name 
        ORDER BY [Date]) AS rn 
     FROM TAB t1) 
SELECT a.ID,a.Name,a.Date,b.Date as nextdate 
FROM cte a 
     LEFT OUTER JOIN cte b 
        ON a.Name = b.Name 
         AND a.rn + 1 = b.rn ORDER BY a.ID 
1

Un altro modo di scrivere sarebbe.

Select a.*, c.nextDate from table a 
outer apply (
     Select top 1 b.Date nextDate from table b 
      where b.Id > a.ID and a.Name = b.Name order by b.id 
) c 
0
SELECT ID 
     ,Name 
     ,Date 
     ,(CASE WHEN ID%2 !=0 THEN NextDate ELSE NULL END) AS NextDate 
FROM 
(SELECT ID 
     ,Name 
     ,Date 
     ,DATEADD(DAY,1,Date) AS NextDate 
FROM YOUR_TABLE) M 
Problemi correlati