2016-12-02 2 views
2

Hier sind meine Eingangsdaten:Wie nummerieren Sie eindeutige Werte unter Berücksichtigung ihrer ursprünglichen Reihenfolge?

CREATE TEMP TABLE test AS SELECT * FROM (VALUES 
    (1, 12), 
    (2, 7), 
    (3, 8), 
    (4, 8), 
    (5, 7) 
) AS rows (position, value); 

Ich mag, in einer einzigen Abfrage (keine Unterabfragen oder CTE), eine eindeutige Nummer für jeden einzelnen value zuweisen. Ich möchte jedoch auch, dass diese Zahlen gemäß dem zugehörigen position aufsteigen - d. H. Eine eindeutige value-Nummer sollte gemäß ihrer niedrigsten position zugewiesen werden. Annahmen

:

  • jede Zeile wird immer eine einzigartige haben position
  • value ist nicht garantiert eindeutig pro Zeile
  • die Nummer eines eindeutigen Wert nur für Ordnungs Zwecke, z.B. es ist egal, ob distinct_values geht 1-2-3 oder 3-8-14

Die gewünschte Ausgabe ist:

position | value | distinct_value 
----------+-------+---------------- 
     1 | 12 |    1 
     2 |  7 |    2 
     3 |  8 |    3 
     4 |  8 |    3 
     5 |  7 |    2 

Ich kann in der Nähe DENSE_RANK erhalten mit unterschiedlichen Werten nummerieren:

SELECT 
    position, 
    value, 
    DENSE_RANK() OVER (ORDER BY value) AS distinct_value 
    FROM test ORDER BY position; 

Das Ergebnis ignoriert offensichtlich position:

position | value | distinct_value 
----------+-------+---------------- 
     1 | 12 |    3 
     2 |  7 |    1 
     3 |  8 |    2 
     4 |  8 |    2 
     5 |  7 |    1 

Gibt es dafür eine bessere Fensterfunktion?

+1

IMO syntaktisch der einfachste Weg ist, '* wählen, array_position ((wählen array_agg (Wert um von Position) von Test), Wert) von Test,' aber es ist offensichtlich nicht effizient für großen Tisch. – Abelisto

Antwort

2
with 
    t(x,y) as (values 
    (1, 12), 
    (2, 7), 
    (3, 8), 
    (4, 8), 
    (5, 7)), 
    pos(i,y) as (select min(x), y from t group by y), 
    ind(i,y) as (select row_number() over(order by i), y from pos) 
select * from ind join t using(y) order by x; 
+0

das funktioniert und ist im Wesentlichen was ich jetzt mache, aber es ist auf einem riesigen Dataset und der Join ist Leistung zu töten, daher die Bestimmung einer einzigen Abfrage – rcrogers

+1

@rocgers Getestet auf 1000000 Zeilen auf meinem 8 Jahre alten Notebook. Für y in 1-100 sind es ungefähr 6 Sekunden und für y in 1-1000 sind es ungefähr 8 Sekunden. Nicht so schnell, aber es sind 1000000 Zeilen ... Auf jeden Fall hoffe ich, dass jemand eine effizientere Lösung findet. – Abelisto

Verwandte Themen