2010-08-03 11 views
55

Ich möchte die Beobachtungsnummer für jeden von einer PostgreSQL-Abfrage zurückgegebenen Datensatz anzeigen.Wie können Zeilennummern in der PostgreSQL-Abfrage angezeigt werden?

Ich denke in 8.4 Windowing-Funktionen können diese Fähigkeit durchführen.

+0

Ich glaube, ich muss meine eigene Frage favorisieren, damit ich in Zukunft wieder dazu kommen kann :) – vol7ron

+24

+1 Dies ist die erste Frage, die ich gesehen habe, die nur aus Fragen, Antworten und Dialogen von einer einzelnen Person besteht . – Xeoncross

+2

:) Xeon, du hast mich gerade zum Lachen gebracht. Ich komme immer wieder auf diese Frage zurück. – vol7ron

Antwort

86
select row_number() over (order by <field> nulls last) as rownum, * 
from  foo_tbl 
order by <field> 

Wenn Auftrag nicht notwendig ist, diese Antwort auch vereinfacht werden kann:

select row_number() over(), * -- notice: no fields are needed 
from foo_tbl 
+1

Es scheint, dass, wenn Sie 'over()' tun, es immer inkrementell, wie '1 2 3 4 ...' * in der Reihenfolge * des bestimmten Ergebnisses (wenn äußere Abfragen, die Ergebnisse neu anordnen, könnte rownum out of order ref: http://stackoverflow.com/a/4812038/32453, so dass das Hinzufügen einer 'order by' in diesen Fällen sinnvoll ist (oder wenn Sie Nullen nicht zählen wollen, wie im ersten Beispiel). FWIW – rogerdpack

+1

Das ist wirklich cool - für uns Neulinge, könnten einige sezieren, wie das funktioniert? –

+2

@ zthomas.nc es ist eine Fensterfunktion.Entwöhnen Sie ein vertrautes Glasfenster.Wenn Sie wollten, könnten Sie dieses Fenster in kleinere Scheiben teilen (Frames), alle Ergebnisse sind immer noch eindeutig dort, aber aufgeteilt über die Frames. Diese Division ist eine sogenannte Partition, was das 'over()' oben tut. Wenn Sie keine Bedingungen angegeben haben, es würde ein Fenster für das gesamte Fenster geben. Fensterfunktionen sind insofern einzigartig, als sie Berechnungen ausführen können ationen über die Zeilen eines Frames statt einer ganzen Ergebnismenge. Wenn du also nach Geschlecht "row_number" machen willst, kannst du dein Over dazu benutzen, nach Geschlecht zu partitionieren. – vol7ron

5

Für Versionen vor 8.4:

SELECT count(*) rownum, foo.* 
FROM  datatable foo 
JOIN  datatable bar 
      ON (foo.pk_id < bar.pk_id) 
GROUP BY foo.pk_id, foo.a, foo.b 
ORDER BY rownum 
; 

-- if there isn't a single unique/primary key field, you can concatenate fields 
-- Example: ON (foo.a||foo.b||foo.c < bar.a||bar.b||bar.c) 

hoffe, das hilft jemand.

+0

Diese Methode sollte auf jeder SQL-Standard-kompatiblen Datenbank funktionieren. – vol7ron

+0

Ich denke, es ist wichtig zu beachten, dass 'null' Werte mit' null' concatentate sein sollten. Daher muss möglicherweise ein 'coalesce()' verwendet werden. – vol7ron

+2

Fensterfunktionen sind Teil des SQL: 2003-Standards. –

Verwandte Themen