2010-08-03 15 views
55

Chciałbym wyświetlić numer obserwacji dla każdego rekordu zwróconego przez zapytanie PostgreSQL.Jak wyświetlić numery wierszy w zapytaniu PostgreSQL?

Myślę, że w 8.4 funkcji okienkowania można wykonać tę funkcję.

+0

Myślę, że muszę sam zadać pytanie, aby móc do niego wrócić w przyszłości :) – vol7ron

+24

+1 To pierwsze pytanie jakie widziałem, które składa się wyłącznie z pytań, odpowiedzi i dialogu od jednej osoby . – Xeoncross

+2

:) Xeon, właśnie mnie rozśmieszyłeś. Wciąż wracam do tego pytania raz na jakiś czas. – vol7ron

Odpowiedz

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

Jeśli zamówienie nie jest to konieczne, to odpowiedź może również zostać uproszczone:

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

Wygląda na to, że jeśli zrobisz 'over()', to zawsze daje przyrosty stopniowo, np. '1 2 3 4 ...' * w kolejności * tego konkretnego wyniku (jeśli są zewnętrzne zapytania, które zmieniają wyniki, to rownum może stają się nieaktualne ref: http://stackoverflow.com/a/4812038/32453, więc dodanie 'order by' może być użyteczne w tych przypadkach (lub jeśli nie chcesz policzyć wartości null, jak w pierwszym przykładzie). FWIW. – rogerdpack

+1

To jest naprawdę fajne - dla nas początkujących, może ktoś rozszyfruje, jak to działa? –

+2

@ zthomas.nc to funkcja okna Pomyśl o znanym szklanym oknie.Jeśli chcesz, możesz podzielić to okno na mniejsze panele (klatki), wszystkie wyniki są tam nadal unikalne, ale podzielone na ramki.To dzielenie jest znane jako partycja, czyli to, co powyżej "over()" .Jeśli nie dostarczyłeś mu żadnych warunków, Dla całego okna byłby jeden panel. Funkcje okna są unikalne, ponieważ mogą wykonywać obliczenia w rzędach ramki, zamiast całego zestawu wyników. Więc jeśli chcesz zrobić 'row_number' według płci, możesz użyć swojej do podziału według płci. – vol7ron

5

W wersjach przed 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) 

Nadzieja to pomaga kogoś.

+0

Ta metoda powinna działać na dowolnej zgodnej z standardem SQL bazie danych – vol7ron

+0

Uważam, że należy pamiętać, że wartości 'null' powinny się kończyć na' null'. W związku z tym konieczne może być użycie opcji "coalesce()". – vol7ron

+2

Funkcje okien są częścią standardu SQL: 2003. –

Powiązane problemy