Ich möchte die Beobachtungsnummer für jeden Datensatz anzeigen, der von einer PostgreSQL-Abfrage zurückgegeben wird.
Ich denke, in 8.4 können Fensterfunktionen diese Fähigkeit ausführen.
sql
database
postgresql
vol7ron
quelle
quelle
Antworten:
select row_number() over (order by <field> nulls last) as rownum, * from foo_tbl order by <field>
Wenn keine Bestellung erforderlich ist, kann diese Antwort auch vereinfacht werden:
select row_number() over(), * -- notice: no fields are needed from foo_tbl
SQL Fiddle Proof of Concept
quelle
over()
dann immer es rownumbers schrittweise, wie gibt ,1 2 3 4...
um dieses spezielle Ergebnis (wenn es äußern Abfragen sind , dass rearrange Ergebnisse, dann rownum aus best.-nr. werden könnten: stackoverflow.com/a/4812038/32453 , so Das Hinzufügen einesorder by
kann in diesen Fällen nützlich sein (oder wenn Sie keine Nullen zählen möchten, wie im ersten Beispiel). FWIW.over()
wie oben beschrieben. Wenn Sie keine Bedingungen angegeben haben, gibt es einen Bereich für das gesamte Fenster.Window functions
sind insofern einzigartig, als sie Berechnungen über die Zeilen eines Frames hinweg anstelle einer gesamten Ergebnismenge durchführen können. Wenn Sie alsorow_number
nach Geschlecht arbeiten möchten, können Sie Ihr Over verwenden, um nach Geschlecht zu unterteilen.Postgres <8.4
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 jemandem.
SQL Fiddle Proof of Concept
Ein anderer Ansatz
Ich schlage vor, dies um jeden Preis zu vermeiden, wollte es aber für die Nachwelt einbeziehen. Es ist etwas teuer und ich kann mir vorstellen, dass es nicht gut skaliert, aber wenn ein Primärschlüssel nicht in einer Tabelle vorhanden ist (schlechtes Datenbankdesign), sind Ihre Optionen möglicherweise eingeschränkt. In den meisten Fällen wird empfohlen, die Nummerierung auf der Anwendungsebene durchzuführen.
-- Based on basic table w/o primary key -- CREATE TABLE names ( name as text ); SELECT num, name[num] FROM ( select generate_series( 1, (select count(*) from names) ) as num ) _nums, ( select array_agg(name) as name from names ) _names
SQL Fiddle Proof of Concept
Gründe, warum es nicht skaliert:
quelle
null
Werte sich darauf konzentrieren solltennull
. Daher musscoalesce()
möglicherweise ein verwendet werden.