2010-08-03 13 views
55

Me gustaría mostrar el número de observación para cada registro devuelto por una consulta de PostgreSQL.¿Cómo se muestran los números de fila en la consulta de PostgreSQL?

Creo que en 8.4 las funciones de ventana pueden realizar esta función.

+0

Creo que tengo que preferir mi propia pregunta para poder volver a esto en el futuro :) – vol7ron

+24

+1 Esta es la primera pregunta que he visto que consiste en preguntas, respuestas y diálogos de una sola persona . – Xeoncross

+2

:) Xeon, me acabas de hacer reír. Todavía vuelvo a hacer esta pregunta de vez en cuando. – vol7ron

Respuesta

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

Si el orden no es necesario, esta respuesta también puede ser simplificado:

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

Parece que si usted hace 'over()', entonces siempre le da a los robots de forma incremental, como '1 2 3 4 ...' * en orden * de ese resultado particular (si hay consultas externas que reorganizan los resultados, entonces rownum podría convertirse fuera de servicio ref: http://stackoverflow.com/a/4812038/32453, por lo que agregar un 'orden por' podría ser útil en esos casos (o si no desea contar nulos, como en el primer ejemplo). FWIW. – rogerdpack

+1

Esto es genial - para nosotros los novatos, ¿podrían algunos diseccionar cómo funciona? –

+2

@ zthomas.nc es una función de ventana. Piense en una ventana de vidrio familiar. Si quisiera, podría dividir esa ventana en paneles más pequeños (marcos), todos los resultados siguen estando únicamente allí, pero divididos entre los cuadros. Esta división es lo que se conoce como una partición, que es lo que hace el 'over()'. Si no le ha proporcionado ninguna condición, Habría un panel para toda la ventana. Las "funciones de ventana" son únicas en cuanto a que pueden hacer cálculo a través de las filas de un marco, en lugar de un conjunto de resultados completo. Entonces, si quisieras hacer 'row_number' por sexo, puedes usar tu para dividir por sexo. – vol7ron

5

Para versiones anteriores a la 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) 

Espero que esto ayude a alguien.

+0

Este método debería funcionar en cualquier base de datos compatible con SQL Standard – vol7ron

+0

Creo que es importante tener en cuenta que los valores 'null' deben concatenarse a' null'. Por lo tanto, es posible que deba usarse un 'coalesce()'. – vol7ron

+2

Las funciones de ventana son parte del estándar SQL: 2003. –

Cuestiones relacionadas