2016-04-04 9 views
0

Ich kam mit einem Problem, das einfach schien, aber ich konnte nicht die gewünschte Ausgabe erhalten. Meine Beispieldaten sind wie folgt: -Wie dichte_Rank() nach der Reihenfolge der Zeilen zu berechnen

end_date_row row_code 
2010-06-30  12 
2011-06-30  12 
2012-06-30  12 
2013-06-30  12 
2014-06-30  12 
2014-07-16  12 
2014-12-31  18 
2015-06-30  18 
2015-07-06  18 
2015-11-17  12 
NULL    18 

ich die Ausgabe wie will - ist

end_date_row row_code rn 
2010-06-30   12  1 
2011-06-30   12  1 
2012-06-30   12  1 
2013-06-30   12  1 
2014-06-30   12  1 
2014-07-16   12  1 
2014-12-31   18  2 
2015-06-30   18  2 
2015-07-06   18  2 
2015-11-17   12  3 
NULL    18  3 

Unterhalb der Code, den ich nahe gebracht, aber ich konnte immer noch nicht die genaue Ausgabe erhalten.

select end_date_row,row_code,rn1 
from 
(
select end_date_row,row_code,row_number() over (order by (select 1)) as rn, row_number() over (order by (select 1)) - row_number() over (partition by row_code order by (end_date_row)) as rn1 
from a 
) as abc 
order by rn 

aus dem obigen Code Meine Ausgabe ist -

end_date_row row_code rn1 
2010-06-30 12 0 
2011-06-30 12 0 
2012-06-30 12 0 
2013-06-30 12 0 
2014-06-30 12 0 
2014-07-16 12 0 
2014-12-31 18 5 
2015-06-30 18 5 
2015-07-06 18 5 
2015-11-17 12 3 
NULL  18 10 

Ich kann nicht lead/lag Funktionen verwenden, wie ich 2008r2 SQL Server verwende. Können wir eine Lösung für dieses Problem ohne rekursive Cte ​​oder While-Schleife haben?

+1

Wie kommt es 'rn = 3' tun? Dort wird 'row_code' geändert. Sollte es nicht "rn = 4" sein? –

Antwort

1

können Sie verwenden Sie die folgende Abfrage:

SELECT end_date_row, row_code, 
     SUM(COALESCE(flag, 0)) OVER 
     (ORDER BY COALESCE(end_date_row, '9999-12-31')) + 1 
FROM (
    SELECT end_date_row, row_code, 
     CASE WHEN row_code <> 
        LAG(row_code) OVER 
        (ORDER BY COALESCE(end_date_row, '9999-12-31')) 
      THEN 1 END AS flag  
    FROM a) AS t 

Demo here

Wenn Sie NULL Werte in end_date_row Feld wollen Hinter als 'keine Änderung' zu behandeln dann dieses verwenden:

SELECT end_date_row, row_code, 
     SUM(COALESCE(flag, 0)) OVER 
     (ORDER BY COALESCE(end_date_row, '9999-12-31')) + 1 
FROM (
    SELECT end_date_row, row_code, 
     CASE WHEN end_date_row IS NOT NULL AND 
        row_code <> 
        LAG(row_code) OVER 
        (ORDER BY COALESCE(end_date_row, '9999-12-31')) 
      THEN 1 END AS flag  
    FROM a) AS t 

Demo here

In SQL-Server 2008 können Sie:

SELECT end_date_row, row_code, 
     DENSE_RANK() OVER (ORDER BY COALESCE(group_date, '9999-12-31')) 
FROM (
    SELECT end_date_row, row_code, 
     MIN(end_date_row) OVER (PARTITION BY grp) AS group_date 
    FROM (
    SELECT end_date_row, row_code, 
     ROW_NUMBER() OVER (ORDER BY COALESCE(end_date_row, '9999-12-31')) - 
     ROW_NUMBER() OVER (PARTITION BY row_code 
          ORDER BY COALESCE(end_date_row, '9999-12-31')) AS grp 
    FROM a) AS t) AS s 

Demo here

+0

Schauen Sie sich die untere Zeile in der Frage an. – sagi

+0

Ich kann keine Lead/Lag-Funktionen verwenden. Ich benutze SQL Server 2008 r2 – sam

+0

@sam Bitte überprüfen Sie die Bearbeitung, die ich gemacht habe. –

0

nicht sicher, aber dies kann für die letzte Zeile

select end_date_row, row_code 
    , dense_rank() over (order by rnA - rnP) as rn 
from (select end_date_row, row_code 
      , row_number() over (      order by end_date_row) as rnA 
      , row_number() over (partition by row_code order by end_date_row) as rnP 
     from a 
    ) tt 
Verwandte Themen