2015-12-24 2 views
6

Ich habe eine Tabelle:Wie der nächste Wert in einer Tabelle finden auf der Grundlage bestimmter Kriterien

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

Ich möchte diese Tabelle so fragen, dass das Ergebnis wird:

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 Lösung ist:

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

Aber das ist sehr langsam, da wir Aggregation auf jeder Reihe tun. Gibt es dafür eine alternative Lösung, die effizienter ist als oben?

+2

Jede Chance, von der SQL Server 2008 bis 2012 oder neuer aktualisieren? Die Funktion [lead] (https://msdn.microsoft.com/en-us/library/hh213125.aspx) scheint genau zu Ihrer Rechnung zu passen. – Mureinik

Antwort

3

Da SQL SERVER 2008 die Fensterfunktion LEAD nicht unterstützt, müssen wir sie mit row_number und self join simulieren. Versuchen Sie diese

;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

Eine andere Möglichkeit, es zu schreiben wäre.

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 
Verwandte Themen