2010-08-03 3 views
55

Я хотел бы показать номер наблюдения для каждой записи, возвращаемой запросом PostgreSQL.Как показать номера строк в запросе PostgreSQL?

Я думаю, что в 8.4 функции окон могут выполнять эту функцию.

+0

Я думаю, что у меня есть любимый мой собственный вопрос, чтобы я мог вернуться к этому в будущем :) – vol7ron

+24

+1 Это первый вопрос, который я видел, который состоит исключительно из вопросов, ответов и диалога от одного человека , – Xeoncross

+2

:) Xeon, ты просто заставил меня рассмеяться. Я все время возвращаюсь к этому вопросу каждый раз. – vol7ron

ответ

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

Если заказ не требуется, этот ответ также может быть упрощен:

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

Похоже, что если вы выполняете 'over()', то он всегда дает рябины инкрементально, например '1 2 3 4 ...' * в порядке * этого конкретного результата (если есть внешние запросы, которые изменяют результаты, тогда rownum может вышли из строя ref: http://stackoverflow.com/a/4812038/32453, поэтому добавление 'order by' может быть полезно в этих случаях (или если вы хотите не считать нули, как в первом примере). FWIW. – rogerdpack

+1

Это действительно здорово - для нас, новичков, может ли кто-нибудь разобраться, как это работает? –

+2

@ zthomas.nc его функция окна. Подумайте о знакомом стеклянном окне. Если бы вы захотели, вы могли бы разделить это окно на более мелкие стекла (фреймы), все результаты по-прежнему однозначно существуют, но делятся на фреймы.Это деление - это то, что известно как раздел, что и делает 'over()' выше.Если вы не предоставили никаких условий, для окна будет одна панель. «Функции окна» уникальны тем, что они могут выполнять вычисления а не по всему набору результатов. Поэтому, если вы хотите сделать «row_number» по полу, вы можете использовать свой раздел для разделения по полу. – vol7ron

5

Для версий до 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) 

Надеется, что это поможет кому-то.

+0

Этот метод должен работать с любой базой данных, совместимой со стандартом SQL. – vol7ron

+0

Я думаю, что важно отметить, что значения «null» должны совпадать с «null». Таким образом, может потребоваться использование 'coalesce()'. – vol7ron

+2

Функции окна являются частью стандарта SQL: 2003. –

Смежные вопросы