SELECT

Nombre

SELECT, TABLE, WITH -- recuperar filas desde una tabla o vista

Sinopsis

[ WITH [ RECURSIVE ] consulta_with [,  ...] ]
SELECT [ ALL | DISTINCT [ ON ( expresión [,  ...] ) ] ]
    * | expresión [ [ AS ] nombre_salida ] [,  ...]
    [ FROM ítem_from [,  ...] ]
    [ WHERE condición ]
    [ GROUP BY expresión [,  ...] ]
    [ HAVING condición [,  ...] ]
    [ WINDOW nombre_ventana AS ( definición_window ) [,  ...] ]
    [ { UNION | INTERSECT | EXCEPT } [ ALL ] sentencia_select ]
    [ ORDER BY expresión [ ASC | DESC | USING operador ] [ NULLS { FIRST | LAST } ] [,  ...] ]
    [ LIMIT { cantidad | ALL } ]
    [ OFFSET inicio [ ROW | ROWS ] ]
    [ FETCH { FIRST | NEXT } [ cantidad ] { ROW | ROWS } ONLY ]
    [ FOR { UPDATE | SHARE } [ OF nombre_tabla [,  ...] ] [ NOWAIT ] […] ]

donde ítem_from puede ser uno de:

    [ ONLY ] nombre_tabla [ * ] [ [ AS ] alias [ ( alias_columna [,  ...] ) ] ]
    ( sentencia_select ) [ AS ] alias [ ( alias_columna  [,  ...] ) ]
    nombre_consulta_with [ [ AS ] alias [ ( alias_columna  [,  ...] ) ] ]
    nombre_function ( [ argumento [,  ...] ] ) [ AS ] alias [ ( alias_columna [,  ...] | definición_columna [,  ...] ) ]
    nombre_función ( [ argumento [,  ...] ] ) AS ( definición_columna [,  ...] )
    ítem_from [ NATURAL ] tipo_junta tem_from [ ON condición_junta | USING ( columna_junta [,  ...] ) ]

y consulta_with es:

    nombre_consulta_with [ ( nombre_columna [,  ...] ) ] AS ( sentencia_select )

TABLE { [ ONLY ] nombre_tabla [ * ] | nombre_consulta_with }

Descripción

SELECT recupera filas de cero o más tablas. El procesamiento general de SELECT es el siguiente:

  1. Todas las consultas en la lista WITH son computadas. Estas sirven efectivamente como tablas temporales que pueden ser referenciadas en la lista FROM. Una consulta WITH que es referenciada más de una vez en el FROM es computada solamente una vez. (Ver Clausula WITH abajo.)
  2. Todos los elementos de la lista FROM son computados. (Cada elemento en la lista FROM es una tabla real o virtual.) Si más de un elemento es especificado en la lista FROM, son unidos cruzadamente (producto cartesiano) entre sí. (Ver Clausula FROM abajo.)
  3. Si una clausula WHERE es especificada, todas las filas que no satisfagan la condición son eliminadas de la salida. (Ver Clausula WHERE abajo.)
  4. Si la clausula GROUP BY es especificada, la salida es dividida en grupos de filas que coinciden en uno o más valores. Si la clausula HAVING está presente, elimina los grupos que no satisfacen la condición dada. (Ver Clausula GROUP BY y Clausula HAVING abajo.)
  5. La salida real es computada usando las expresiones de salida del SELECT para cada fila seleccionada. (Ver Lista SELECT abajo.)
  6. Usando los operadores UNION, INTERSECT, y EXCEPT, la salida de más de una instrucción SELECT puede ser combinada para formar un conjunto de resultados único. El operador UNION devuelve todas las filas que estan en una o en ambos conjuntos de resultados. El operador INTERSECT devuelve todas las filas que estan estrictamente en ambos conjuntos de resultados. El operador EXCEPT devuelve las filas que estan en el primer conjunto de resultados y no en el segundo. En los tres casos, las filas duplicadas son eliminadas salvo que se especifique ALL. (Ver Clausula UNION, Clausula INTERSECT, y Clausula EXCEPT abajo.)
  7. Si la clausula ORDER BY es especificada, las filas devueltas son ordenadas en el órden especificado. Si ORDER BY no es dado, las filas son devueltas en cualquier orden que el sistema encuentre más rápido de producir. (Ver Clausula ORDER BY abajo.)
  8. DISTINCT elimina filas repetidas del resultado. DISTINCT ON elimina filas que coinciden con todas las expresiones especificadas. ALL (por defecto) devolverá todas las filas candidatas, incuyendo duplicados. (Ver Clausula DISTINCT abajo.)
  9. Si es especificada la clausula LIMIT (o FETCH FIRST) o OFFSET , la instrucción SELECT solo devuelve un subconjunto de las filas resultantes. (Ver Clausula LIMIT abajo.)
  10. Si se especifica FOR UPDATE o FOR SHARE, la instrucción SELECT bloquea las filas seleccionadas contra actualizaciones concurrentes. (Ver Clausula FOR UPDATE/FOR SHARE Clause abajo.)

Debe tener privilegios SELECT en cada columna usada en una órden SELECT. A su vez, el uso de FOR UPDATE o FOR SHARE requiere privilegios UPDATE (al menos por cada columna de cada tabla a ser seleccionada).

Parámetros

Clausula WITH

La clausula WITH permite especificar uno o más subconsultas que serán referenciadas por su nombre en la consulta principal. Las consultas efectivamente actúan como unas tablas o vistas temporales por la duración de la consulta primaria.

Un nombre (sin calificador de esquema) debe ser especificado a cada consulta WITH. Opcionalmente, una lista de nombres puede ser especificada: si es omitida, el nombre de las columnas serán inferidos de la subconsulta.

Si se especifica RECURSIVE, permite a una subconsulta referenciar a sí misma. Dicha subconsulta debe tener la forma

término_no_recursivo UNION [ ALL ] término_recursivo

donde la referencia recursiva a si misma debe aparecer en el lado derecho de la UNION. Solo se permite una referencia a si misma por consulta.

Otro efecto de RECURSIVE es que las consultas WITH no necesitan ser ordenadas: una consulta puede referenciar otra que esté luego en esta lista. (Aunque no estan implementadas las referencias circulares o recursión mutua) Sin RECURSIVE, las consultas WITH solo pueden referenciar consultas WITH hermanas que son anteriores en la lista WITH.

Una propiedad útil de las consultas WITH es que son evaluadas solo una vez por cada ejecución de la consulta principal, aún si la consulta primaria se refiere a ellas más de una vez.

Ver  Section 7.8 para información adicional.

Clausula FROM

La clausula FROM especifica una o más tablas de origen para el SELECT. Si multiples orígenes son especificados, el resultado es el producto Cartesiano (junta cruzada) de todos los orígenes. Pero usualmente son agregadas condiciones de calificación para restringir las filas devueltas a un pequeño subconjunto del producto Cartesiano.

La clausula FROM puede contener los siguientes elementos:

nombre_tabla
El nombre (opcionalmente calificado por el esquema) de una tabla existente o vista. Si se especifica ONLY, solo una tabla es recorrida. Si no se especifica ONLY, la tabla y cualquiera de sus descendientes es recorrida.
alias
Un sustituto para el nombre del item FROM conteniendo el alias. Un alias es usado por brevedad o para eliminar ambiguedades entre juntas a si mismas (donde la misma tabla es recorrida múltiples veces). Cuando se provee un alias, oculta completamente el nombre real de la tabla o función; por ejemplo dado FROM foo AS f, el resto del SELECT debe referise a este ítem FROM como f y no foo. Si un alias es escrito, un alias de columna puede ser también escrito para proveer nombres sustitutos para una o más columnas de la tabla.
select
Un sub-SELECT puede aparecer en la clausula FROM. Este actua como si su salida fuera creada como una tabla temporal por la duración de una órden SELECT simple. Notar que los sub-SELECT deben ser rodeados con paréntesis, y un alias debe ser provisto para el. Una órden  VALUES puede ser usada también aquí.
nombre_consulta_with
Una consulta WITH es referenciada escribiendo su nombre, simplemente como si el nombre de la consulta fuera un nombre de tabla. (De hecho, la consulta WITH oculta cualquier tabla real del mismo nombre a la consulta primaria. Si es necesario, puede referirse a la tabla real del mismo nombre al calificar con el esquema el nombre de la tabla.) Un alias puede ser provisto de la misma manera que para una tabla.
nombre_función
En la clausula FROM pueden aparecer llamadas a función. (Esto es especialmente útil para funciones que devuelven conjuntos de resultados, pero cualquier función puede ser usada.) Actua como si su salida fuera creada a modo de tabla temporal por la duración de la órden SELECT original. También se puede usar un alias. Si se escribe un alias, una lista de alias de columna puede ser también escrita para proveer nombres sustitutos de uno o más atributos del tipo de retorno compuesto de la función. Si la función ha sido definida que devuelve el tipo de datos record, un alias o palabra clave AS debe estar presente, seguido por una lista de definición de columnas en la forma ( nombre_column tipo_dato [, ... ] ). La lista de definición de columna debe coincidir con la cantidad y tipo de datos devueltos por la función.
tipo_junta
Uno de:
  • [ INNER ] JOIN
  • LEFT [ OUTER ] JOIN
  • RIGHT [ OUTER ] JOIN
  • FULL [ OUTER ] JOIN
  • CROSS JOIN

Para los tipos de junta INNER y OUTER, una condicion debe ser especificada, a saber exactamente una de NATURAL, ON condición_junta, o USING (columna_junta [, ...]). Ver abajo por su significado.Para CROSS JOIN, ningúna de estas clausulas pueden aparecer.

Una clausula JOIN combina dos items FROM. Usar paréntesis si es necesario determinar el orden de anidamiento. En ausencia de paréntesis, los JOINs se anidan de izquierda a derecha. En cualquier caso JOIN se enlaza más estrechamente que separando por comas los items FROM.

CROSS JOIN e INNER JOIN producen un producto Cartesiano simple, el mismo resultado que obtendría de listar los dos items en primer nivel del FROM, pero restringidos por la condición de junta (si existe). CROSS JOIN es equivalente a INNER JOIN ON (TRUE), dicho de otro modo, ninguna fila es removida por calificación. Estos tipos de junta son solo una conveniencia de notación, ya que no hacen más de lo que se podría hacer con FROM y WHERE simples.

LEFT OUTER JOIN devuelve todas las filas en el producto Cartesiano calificadas (todas las filas combinadas que cumplieron la condición de junta), más una copia de cada fila en la tabla izquierda para la cual ninguna fila derecha cumplió la condición de junta. Esta fila izquierda es extendida al ancho total de la tabla juntada insertando valores nulos para las columnas derechas. Note que solo la condición propia de la clausula JOIN es conciderada mientras se decide que filas tienen coincidencias. Las condiciones externas son aplicadas después.

A la inversa, RIGHT OUTER JOIN devuelve todas las filas combinadas, más una por cada fila derecha sin coincidencias (extendida a la izquierda con nulos). Esto es solo una conveniencia de notación, ya que podría convertirla a LEFT OUTER JOIN cambiando las entrada izquierda por derecha.

FULL OUTER JOIN devuelve todas las filas combinadas, más una fila por cada una sin coincidencia izquierda (extendido con nulos a la derecha), más una fila por cada una sin coincidencia derecha (extendido con nulos a la izquierda).

ON condición_junta
condición_junta es una expresión resultando en valores del tipo boolean (similar a la clausula WHERE) que especifican que filas en una junta son concideradas que coinciden.
USING ( columna_junta [, ...] )
Una clausula de la forma USING ( a, b, ... ) es la forma reducida de ON tabla_izquierda.a = tabla_derecha.a AND tabla_izquierda.b = tabla_derecha.b ....A su vez , USING implica que solo una de cada par de columnas equivalentes será incluida en la salida de la junta, no ambas.
NATURAL
NATURAL es la forma reducida de una lista USING que mencione todas las columnas en las dos tablas que tienen el mismo nombre.

Clausula WHERE

La clausula opcional WHERE tiene la forma general

WHERE condición

donde condición es cualquier expresión que evalua a un resultado de tipo boolean. Cualquier fila que no satisface esta condición será eliminada de la salida. Una fila satisface la condición si esta devuelve verdadero cuando los valores de la fila actual son sustituidos por las referencias a variables.

Clausula GROUP BY

La clausula opcional GROUP BY tiene la siguiente forma general

GROUP BY expresión [,  ...]

GROUP BY condensará en una única fila todas las filas seleccionadas que compartan los mismos valores para las expresiones de agrupamiento. expresión puede ser un nombre de columna de entrada, o el nombre o el número ordinal de una columna de salida (items lista SELECT), o una expresión arbitraria formada por valores de las columnas de entrada. En caso de ambiguedad, el nombre en GROUP BY será interpretado como el nombre de una columna de entrada antes que el de una de salida.

Funciones de agregado, si alguna es usada, son computadas sobre todas las filas que conforman cada grupo, produciendo un valor separado para cada grupo (mientras que sin GROUP BY, un agregado produce un valor individual computado sobre todas las filas seleccionadas). Cuando GROUP BY está presente, no es válido para la lista de expresiones del SELECT referirse a columnas no agrupadas excepto entre las funciones de agregado, ya que habría más de un posible valor a devolver de una columna sin agrupar.

Clausula HAVING

La clausula HAVING opcional tiene la forma general

HAVING condición

donde condición es idéntico a lo especificado para la clausula WHERE.

HAVING elimina filas agrupadas que no satisfacen la condición. HAVING es diferente a WHERE: WHERE filtra filas individuales antes de la aplicación de GROUP BY, mientras que HAVING filtra filas agrupadas creadas por GROUP BY. Cada columna referenciada en condición debe referenciar sin ambiguedad una columna de agrupación, salvo que la referencia aparezca dentro de una función de agregado.

La presencia de HAVING torna a la consulta en una consulta agrupada aún si no hay clausula GROUP BY. Esto es lo mismo que sucede cuando una consulta contiene funciones de agregado sin clausula GROUP BY. Todas las filas seleccionadas son consideradas que forman un grupo individual, y la lista SELECT y clausula HAVING solamente puede referenciar columnas de tabla desde funciones agregadas. Dicha consulta emitirá solo una fila si la condición HAVING es verdadera, cero filas si es falsa.

Clausula WINDOW

La clausula opcional WINDOW tiene la siguiente forma

WINDOW nombre_ventana AS ( definición_ventana ) [,  ...]

donde nombre_ventana es el nombre que puede ser referenciado desde definiciones subsecuentes de ventanas o clausulas OVER, y definición_ventana es

[ nombre_ventana_existente ]
[ PARTITION BY expresión [,  ...] ]
[ ORDER BY expresión [ ASC | DESC | USING operador ] [ NULLS { FIRST | LAST } ] [,  ...] ]
[ clausula_marco ]

Si se especifica nombre_ventana_existente debe referirse a una entrada anterior en la lista WINDOW; la nueva ventana copia su clausula de particionamiento de aquella entrada, y lo mismo para su clausula de ordenamiento si existe. En este caso la nueva ventana no puede especificar su propia clausula PARTITION BY, y puede especificar ORDER BY solo si la ventana copiada no tiene una. La nueva ventana siempre usa so propia clausula marco; la ventana copiada no debe especificar una clausula marco.

Los elementos de la lista PARTITION BY son interpretados en una manera muy similar a los elementos en una Clausula GROUP BY, exceptuando que son siempre expresiones simples y nunca el nombre o numero de una columna de salida. Otra diferencia es que estas expresiones pueden contener llamadas a funciones de agregado, que no son permitidas en una clausula GROUP BY normal . Son permitidas aquí porque las ventanas ocurren después de la agrupación y agregación.

Similarmente, los elementos de una lista ORDER BY son interpretados en una manera muy similar a los elementos en una Clausula ORDER BY, exceptuando que la expresión siempre son tomadas como expresiones simples y nunca el nombre o número de una columna de salida.

La clausula_marco opcional define el marco de ventana para funciones de ventana que dependan de este marco (no todas lo hacen). Puede ser una de

RANGE UNBOUNDED PRECEDING
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
ROWS UNBOUNDED PRECEDING
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

Las primeras dos son equivalente y también son las predeterminadas: establecen que el marco serán todas las filas de la partición empezando a través del último par de la fila actual en el ordenamiento ORDER BY (lo que significa que serán todas las filas si no hay ORDER BY). Las opciones RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING y ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING son equivalentes: siempre seleccionan todas las filas de la partición. Par último, ROWS UNBOUNDED PRECEDING o su equivalente ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW seleccionan todas las filas hasta la fila actual (sin importar los duplicados). Tener cuidado ya que esta opción puede producir resultados dependientes de la implementación si el orden ORDER BY no ordena las filas de manera única.

El propósito de la clausula WINDOW es especificar el comportamiento de las funciones de ventana apareciendo en la lista SELECT o Clausula ORDER BY de la consulta. Estas funciones pueden referenciar entradas de la clausula WINDOW por su nombre en sus clausulas OVER. Una entrada de clausula WINDOW no necesita ser referenciada en otro lugar, aunque; si no es usada en la consulta simplemente es ignorada. Es posible usar funciones de ventana sin siquiera una clausula WINDOW, ya que una llamada a función de ventana puede especificar su definición de ventana directamente en su clausula OVER. Sin embargo, la clausula WINDOW ahorra tipear cuando la misma definición de ventana es necesaria para más de una función de ventana.

Funciones de ventana son descritas en detalle en  Section 3.5,  Section 4.2.8, y  Section 7.2.4.

Lista SELECT

La lista SELECT (entre las palabras clave SELECT y FROM) especifican expresiones que forman las filas de salida de la sentencia SELECT. Las expresiones pueden (y usualmente lo hacen) referirse a columnas computadas en la clausula FROM.

Del mismo modo que en una tabla, cada columna de salida de un SELECT tiene un nombre. En un SELECT simple este nombre simplemente es utilizado para etiquetar la columna para mostrarla, pero cuando el SELECT es una sub-consulta de una consulta mayor, el nombre es visto por la consulta mayor como el nombre de columna de una tabla virtual producida por la subconsulta. Para especificar el nombre a usar para una columna de salida, escribir AS nombre_salida despues de la expresión de la columna. (Se puede omitir el AS, pero solo si el nombre de salida deseado no coincide con ninguna palabra clave de PostgreSQL (ver  Appendix C). Para protección frente a posibles adiciones de palabras clave futuras, se recomienda siempre escribir AS o encerrar con comillas dobles el nombre de salida.) Si no se especifica el nombre de columna, PostgreSQL elije un nombre automáticamente. Si la expresión de la columna es una referencia simple a otra columna, el nombre elegido es el mismo que dicha referencia, en casos más complejos se elije usualmente un nombre generado parecido a ?columnN?.

Un nombre de columna de salida puede ser usado para referirse al valor de dicha columna en las clausulas ORDER BY y GROUP BY, pero no en las clausulas WHERE o HAVING; allí se debe escribir la expresión completa.

En vez de una expresión, se puede escribir * en la lista de salida como un atajo para especificar todas las columnas de las filas seleccionadas. Además, puede escribir nombre_tabla.* como un atajo para especificar las columnas que vienen solo de esa tabla. En estos casos no es posible especificar nuevos nombres con AS; el nombre de la columna de salida será el mismo que el nombre de columna de la tabla.

Clausula UNION

La clausula UNION tiene la forma general:

sentencia_select UNION [ ALL ] sentencia_select

sentencia_select es cualquier sentencia SELECT sin clausulas ORDER BY, LIMIT, FOR UPDATE, o FOR SHARE. (ORDER BY y LIMIT pueden adjuntarse a una subexpresión si se encierran entre paréntesis. Sin paréntesis, estas clausulas serán aplicadas sobre el resultado de la UNION, no sobre sus expresiones.)

El operador UNION computa la union de conjunto de las filas devueltas por las sentencias SELECT involucradas. Una fila está en la unión de los dos conjuntos de resultados si aparece en al menos uno de los conjuntos de resultados. Las dos sentencias SELECT que representan los operadores directos de la UNION deben producir el mismo número de columnas, y las columnas correspondientes deben ser de tipos de datos compatibles.

El resultado de la UNION no contiene ninguna fila duplicada salvo que se especifique la opción ALL. ALL previene la eliminación de duplicados. (Por lo tanto, UNION ALL es usualmente más rápido que UNION; usar ALL cuando sea posible.)

Multiples operadores UNION en la misma sentencia SELECT son evaluados de izquierda a derecha, salvo que se indique lo contrario con paréntesis.

Actualmente, FOR UPDATE y FOR SHARE no pueden ser especificados ya sea para el resultado de una UNION o para cualquiera de sus entradas a la UNION.

Clausula INTERSECT

La clausula INTERSECT tiene esta forma general:

sentencia_select INTERSECT [ ALL ] sentencia_select

sentencia_select es cualquier sentencia SELECT sin clausulas ORDER BY, LIMIT, FOR UPDATE, o FOR SHARE.

El operador INTERSECT computa la intersección de conjuntos de las filas devueltas por las sentencias SELECT involucradas. Una fila está en la intersección de dos conjuntos de resultados si aparece en ambos conjuntos de resultados.

El resultado de INTERSECT no contiene ninguna fila duplicada salvo que se especifique la opción ALL. Con ALL, una fila que tiene m duplicados en la tabla izquierda y n duplicados en la tabla derecha aparecerá min(m,n) veces en el conjunto de resultado.

Operadores INTERSECT múltipes en la misma sentencia SELECT son evaluados de izquierda a derecha, salvo que paréntesis indiquen lo contrario. INTERSECT se une mas etrechamente que UNION. Esto es, A UNION B INTERSECT C será leido como A UNION (B INTERSECT C).

Actualmente, FOR UPDATE y FOR SHARE no pueden ser especificados ya sea para el resultado de una INTERSECT o para cualquiera de las entradas de INTERSECT.

Clausula EXCEPT

La clausula EXCEPT tiene esta forma general:

sentencia_select EXCEPT [ ALL ] sentencia_select

sentencia_select es cualquier sentencia SELECT sin clausulas ORDER BY, LIMIT, FOR UPDATE, o FOR SHARE.

El operador EXCEPT computa un conjunto de filas que están en el resultado de la sentencia SELECT izquierda pero no estan en el resultado del de la derecha.

El resultado de EXCEPT no contiene ninguna fila duplicada salvo que se especifique la opción ALL. Con ALL, una fila que tiene m duplicados en la tabla izquierda y n duplicados en la tabla derecha aparecerá max(m,n, 0) veces en el conjunto de resultado.

Múltiples operadores EXCEPT en la misma sentencia SELECT son evaluados de izquierda a derecha, salvo que paréntesis indiquen lo contrario. EXCEPT se vincula al mismo nivel que UNION.

Actualmente, FOR UPDATE y FOR SHARE no pueden ser especificados ya sea para el resultado de una EXCEPT o para cualquiera de las entradas de EXCEPT.

Clausula ORDER BY

La clausula ORDER BY tiene esta forma general:

ORDER BY expresión [ ASC | DESC | USING operador ] [ NULLS { FIRST | LAST } ] [,  ...]

La clausula ORDER BY causa que las filas resultantes sean ordenadas de acuerdo a la(s) expresión(es) especificadas. Si dos filas son iguales de acuerdo a la expresión a la izquierda, son comparadas de acuerdo a la expresión siguiente y así sucesivamente. Si son iguales con respecto a todas las expresiones especificadas, son devueltas en un orden dependiendo de la implementación.

Cada expresión puede ser el nombre o número ordinal de una columna de salida (ítem de la lista SELECT), o puede ser una expresión arbitraria formada por varios valores de columnas de entrada.

El número ordinal se refiere a la posición (de izquierda a derecha) de la columna de salida. Esta característica hace posible definir un ordenamiento en base a una columna que no tiene un nombre único. Esto nunca es absolutamente necesario ya que siempre es posible asignar un nombre a una columna de salida usando la clausula AS.

También es posible usar expresiones arbitrarias en la clausula ORDER BY, incluyendo columnas que no aparecen en la lista de salida del SELECT. Por lo que la siguiente sentencia es válida:

SELECT name FROM distributors ORDER BY code;

Una limitación de esta característica es que una clausula ORDER BY aplicando al resultado de clausulas UNION, INTERSECT, o EXCEPT debe especificar un nombre de columna de salida o su número, no una expresión.

Si una expresión ORDER BY es un simple nombre que coincide con una columna de salida y una de entrada a la vez, ORDER BY lo interpretará como el nombre de la columna de salida. Esta es la elección opuesta a la que hará GROUP BY en la misma situación. Esta inconsistencia es hecha para ser compatible con el estándar SQL.

Opcionalmente, uno puede agregar la palabra clave ASC (ascendente) o DESC (descendente) despues de cualquier expresión en la clausula ORDER BY. Si no se especifica, ASC es asumido por defecto. Alternativamente, un nombre de operador de ordenamiento específico puede ser especificado usando la clausula USING. Un operador de ordenamiento debe ser un miembro menor-que o mayor-que de alguna familia de operadores B-tree. ASC es usualmente equivalente a USING < y DESC es usualmente equivalente a USING >. (Pero el creador de un tipo de datos definido por el usuario puede determinar cual es el ordenamiento por defecto, y podría corresponder a operadores con otros nombres.)

Si se especifica NULLS LAST, los valores nulos son ordenados después de todos los valores no nulos; si se especifica NULLS FIRST, los valores nulos se ordenan antes que todos los no nulos. Si ninguno es especificado, el comportamiento por defecto es NULLS LAST cuando se especifica ASC o está implícito, y NULLS FIRST cuando se especifica DESC (por lo tanto, por defecto se actúa como si los nulos fueran mayores que los no nulos). Cuando se especifica USING, el ordenamiento por defecto de los nulos depende de si el operador es menor-que o mayor-que.

Note que el las opciones de ordenamiento aplican solo a las expresiones que siguen; por ejemplo ORDER BY x, y DESC no significa lo mismo que ORDER BY x DESC, y DESC.

Los datos de cadenas de caracteres son ordenados de acuerdo al orden intercalación específica de la configuración regional establecido cuando la base de datos fue creada.

Clausula DISTINCT

Si se especifica DISTINCT, todas las filas duplicadas son eliminadas del conjunto resultado (una fila es mantenida de cada grupo de duplicados). ALL especifica lo contrario: todas las filas son mantenidas; este es lo predeterminado.

DISTINCT ON ( expresión [, ...] ) mantiene solo la primer fila de cada conjunto de filas cuando la expresión dada evalúa a igualdad. Las expresiones DISTINCT ON son interpretadas usando las mismas reglas que para ORDER BY (ver arriba). Note que la "primer fila" de cada conjunto de filas es impredecible a menos que ORDER BY sea usado para asegurar que la fila deseada aparezca primero. Por ejemplo:

SELECT DISTINCT ON (localidad) localidad, fecha, reporte
    FROM reportes_clima
    ORDER BY localidad, fecha DESC;

recupera el reporte de clima más reciente para cada localidad. Pero si no hubieramos usado ORDER BY para forzar el orden descendiente de valores de fecha para cada localidad, hubiéramos obtenido un reporte de una fecha impredecible para cada localidad.

La expresión(es) DISTINCT ON debe coincidir con la expresión(es) ORDER BY a la izquierda. La clausula ORDER BY normalmente contendrá expresión(es) adicionales que determinen la precedencia deseada de las filas dentro de cada grupo DISTINCT ON.

Clausula LIMIT

La clausula LIMIT consiste de dos sub-clausulas independientes:

LIMIT { cantidad | ALL }
OFFSET inicio

cantidad especifica el máximo numero de filas a devolver, mientras que inicio especifica el numero de filas a saltear antes de empezar a devolver filas. Cuando se especifican ambas, se saltean el número de filas dado por inicio antes de empezar a contar las filas a devolver dado por cantidad .

Si la expresión cantidad evalúa a NULL, es tratada como LIMIT ALL, o sea, sin límite. Si inicio evalúa a NULL, es tratado como OFFSET 0.

SQL:2008 introdujo una sintaxis diferente para archivar el mismo efecto, que PostgreSQL también soporta. Ello es:

OFFSET inicio { ROW | ROWS }
FETCH { FIRST | NEXT } [ cantidad ] { ROW | ROWS } ONLY

Ambas clausulas son opcionales, pero si la clausula OFFSET esta presente debe estar antes que la clausula FETCH. ROW y ROWS como también FIRST y NEXT son palabras are noise words que no influencian el efecto de estas clausulas. En esta sintaxis, cuando se usan expresiones que no sean constantes simples inicio o cantidad, serán necesarios paréntesis en la mayoría de los casos. Si cantidad es omitida en el FETCH, por defecto es 1.

Cuando se use LIMIT, es una buena idea usar la clausula ORDER BY que restringe las filas de resultado en un orden único. De lo contrario obtendrá un subconjunto impredecible de las filas de consultas - estaría pidiendo por las filas décima a la vigécima, ¿pero en que orden? No se sabe el orden si no se especifica ORDER BY.

El planeador de consultas toma en cuenta el LIMIT cuando está generando el plan de consulta, por lo que seguramente obtendrá diferentes planes (obteniendo filas en diferente orden) depediendo en que usa para LIMIT y OFFSET. Por lo tanto, usando valores diferentes en LIMIT/OFFSET para seleccionar diferentes subconjuntos del resultado de una consulta dará resultados inconsistentes salvo que asegure un ordenamiento predecible del resultado con ORDER BY. Esto no es un bug; es una consecuencia inherente del hecho que SQL no promete entregar los resultados de una consulta en un orden particular salvo que se use ORDER BY para restringir el orden.

Aún es posible para ejecuciones repetidas de la consulta con el mismo LIMIT devolver subconjuntos diferentes de filas para una tabla, si no hay una clausula ORDER BY para asegurar la selección de un subconjunto determinista. Nuevamente, esto no es un bug; el determinismo de los resultados simplemente no esta garantizado en dicho caso.

Clausula FOR UPDATE/FOR SHARE

La clausula FOR UPDATE tiene esta forma:

FOR UPDATE [ OF nombre_tabla [,  ...] ] [ NOWAIT ]

La clausula FOR SHARE estrechamente relacionada tiene esta forma:

FOR SHARE [ OF nombre_tabla [,  ...] ] [ NOWAIT ]

FOR UPDATE causa que las filas recuperadas por la sentencia SELECT se bloquearán como si se fueran a actualizar. Esto previene que sean modificadas o borradas por otras transacciones hasta que la transacción actual termina. Esto es, otras transacciones que intenten UPDATE, DELETE, o SELECT FOR UPDATE de estas filas serán bloqueadas hasta que la transacción actual termina. Además, si un UPDATE, DELETE, o SELECT FOR UPDATE de otra transacción ya ha bloqueado la fila o filas seleccionadas, SELECT FOR UPDATE esperará a que la otra transacción se complete, y entonces bloqueará y devolverá las filas actualizadas (o ninguna fila, si fueron eliminadas). Para discusión posterior ver  Capítulo 13.

Para prevenir la operación de esperar para que otra transacción sea comprometida, usar la opción NOWAIT. SELECT FOR UPDATE NOWAIT reporta un error, en vez de esperar, si la fila seleccionada no puede ser bloqueada inmediatamente. Note que NOWAIT aplica solo a los bloqueos a nivel de fila - los bloqueos requeridos a nivel de tabla ROW SHARE se toman igualmente de la manera ordinaria (ver  Capítulo 13). Puede usar la opción NOWAIT de  LOCK si necesita adquirir el bloqueo a nivel de tabla sin esperar.

FOR SHARE se comporta de manera similar, a excepción de que adquiere el bloqueo compartido en vez de uno exclusivo sobre cada fila devuelta. Un bloqueo compartido bloquea otras transacciones de ejecutar UPDATE, DELETE, o SELECT FOR UPDATE en estas filas, pero no las previene de ejecutar SELECT FOR SHARE sobre ellas.

Si tablas específicas son nombradas en FOR UPDATE o FOR SHARE, entonces solo las filas que vengan de dichas tablas seran bloqueadas; cualquier otra tabla usada en SELECT son simplemente leídas de manera usual. Una clausula FOR UPDATE o FOR SHARE sin una lista de tablas afecta a todas las tablas involucradas en la orden. Si FOR UPDATE o FOR SHARE se aplica a una vista o subconsulta, afecta a todas las tablas usadas en la vista o sub-consulta.

Multiples clausulas FOR UPDATE y FOR SHARE pueden ser escritas si se necesita especificar comportamientos de bloqueos diferentes para diferentes tablas. Si se menciona la misma tabla (o es afectada implícitamente) por ambas clausulas FOR UPDATE y FOR SHARE, entonces son procesadas como FOR UPDATE. Similarmente, una tabla es procesada como NOWAIT si aquella es especificada en cualquiera de las clausulas que la afectan.

FOR UPDATE y FOR SHARE no pueden ser usadas en contextos donde las filas devueltas no pueden ser claramente identificadas como filas individuales de una tabla; por ejemplo no puede ser usada con agregados.

Advertencia
Evitar bloquear una fila y modificarla dentro de un punto de retorno posterior o un bloque de excepción PL/pgSQL. Una vuelta atrás causaría que el bloqueo se perdiera. Por ejemplo:
BEGIN;
SELECT * FROM mitabla WHERE clave = 1 FOR UPDATE;
SAVEPOINT s;
UPDATE mitabla SET ... WHERE clave = 1;
ROLLBACK TO s;
Luego del ROLLBACK, la fila es efectivamente desbloqueada, en vez de volver al estado previo al punto de retorno (SAVEPOINT) de estar bloqueada pero no modificada. Este peligro ocurre si la fila bloqueada en la transacción actual es actualizada o eliminada, o si el bloqueo compartido es mejorado a exclusivo: en todos los casos, el estado de bloqueo anterior es olvidado. Si la transacción es vuelta atrás a un estado entre la orden de bloqueo original y el cambio subsiguiente, la fila aparecerá no bloqueda en absoluto. Esto es una deficiencia de la implementación que será encauzada en una liberación futura de PostgreSQL.
Advertencia
Es posible que una orden SELECT usando ambas clausulas LIMIT y FOR UPDATE/SHARE devolver menos filas que las especificadas por LIMIT. Esto es porque LIMIT es aplicado primero. La orden selecciona el número de filas especificado, pero podría bloquearse intentando obtener un bloqueo sobre una o más de ellas. Una vez que el SELECT se desbloquea, las filas podrían haber sido eliminadas o actualizadas por lo que ya no cumplirían la condición WHERE de la consulta, en cuyo caso no serán devueltas.
Advertencia
Similarmente, es posible para una orden SELECT usando ORDER BY y FOR UPDATE/SHARE devolver filas fuera de orden. Esto ocurre porque ORDER BY se aplica primero. La orden ordena el resultado, pero luego podría bloquearse intentando bloquear una o más filas. Una vez que el SELECT se desbloquea, una de las columnas ordenadas podría haber sido modificada y se devolverá fuera de orden. Un arreglo provisorio es ejecutar SELECT ... FOR UPDATE/SHARE y luego SELECT ... ORDER BY.

Orden TABLE

La orden

TABLE nombre_tabla 

es completamente equivalente a

SELECT * FROM nombre_tabla

Puede se usado como una orden de alto nivel o como una variante de sintaxis para ahorrar espacio en partes de una consulta compleja.

Ejemplos

Para juntar la tabla peliculas con la tabla distribuidores:

SELECT p.titulo, p.did, d.nombre, p.fecha_prod, p.genero
    FROM distribuidores d, peliculas p
    WHERE p.did = d.did

       titulo      | did |    nombre    | fecha_prod |  genero
-------------------+-----+--------------+------------+----------
 The Third Man     | 101 | British Lion | 1949-12-23 | Drama
 The African Queen | 101 | British Lion | 1951-08-11 | Románce
 ...

Para sumar la columna duracion de todos los filmes y agrupar los resultados por genero:

SELECT genero, sum(duracion) AS total FROM peliculas GROUP BY genero;

  genero  | total
----------+-------
 Acción   | 07:34
 Comedia  | 02:58
 Drama    | 14:28
 Musical  | 06:42
 Romance  | 04:38

Para sumar la columna duracion de todos los filmes, agrupar los resultados por genero y mostrar aquellos totales de grupo que son mayores a 5 horas:

SELECT genero, sum(duracion) AS total
    FROM peliculas
    GROUP BY genero
    HAVING sum(duracion) < interval '5 hours';

  genero  | total
----------+-------
 Comedia  | 02:58
 Romance  | 04:38

Los siguientes dos ejemplos son maneras idénticas de ordenar los resultados individuales de acuerdo a los contenidos de la segunda columna (nombre):

SELECT * FROM distribuidores ORDER BY nombre;
SELECT * FROM distribuidores ORDER BY 2;

 did |       nombre
-----+------------------
 109 | 20th Century Fox
 110 | Bavaria Atelier
 101 | British Lion
 107 | Columbia
 102 | Jean Luc Godard
 113 | Luso films
 104 | Mosfilm
 103 | Paramount
 106 | Toho
 105 | United Artists
 111 | Walt Disney
 112 | Warner Bros.
 108 | Westward

El siguiente ejemplo muestra como obtener la unión de la tabla distribuidores y actores, restringiendo los resultados a aquellos que comienzan con la letra W en cada tabla. Solo filas distintas son requeridas, por lo que se omite la palabra clave ALL.

distribuidores:             actores:
 did |     nombre            id |     nombre
-----+--------------        ----+----------------
 108 | Westward               1 | Woody Allen
 111 | Walt Disney            2 | Warren Beatty
 112 | Warner Bros.           3 | Walter Matthau
 ...                         ...

SELECT distribuidores.nombre
    FROM distribuidores
    WHERE distribuidores.nombre LIKE 'W%'
UNION
SELECT actores.nombre
    FROM actores
    WHERE actores.name LIKE 'W%';

     nombre
----------------
 Walt Disney
 Walter Matthau
 Warner Bros.
 Warren Beatty
 Westward
 Woody Allen

Este ejemplo muestra como usar una función en la clausula FROM, con y sin una lista de definición de columnas:

CREATE FUNCTION distribuidores(int) RETURNS SETOF distribuidores AS $$
    SELECT * FROM distribuidores WHERE did = $1;
$$ LANGUAGE SQL;

SELECT * FROM distribuidores(111);
 did |    nombre
-----+-------------
 111 | Walt Disney

CREATE FUNCTION distribuidores_2(int) RETURNS SETOF record AS $$
    SELECT * FROM distribuidores WHERE did = $1;
$$ LANGUAGE SQL;

SELECT * FROM distribuidores_2(111) AS (f1 int, f2 text);
 f1  |     f2
-----+-------------
 111 | Walt Disney

Este ejemplo muestra como usar una clausula WITH simple:

WITH t AS (
    SELECT random() as x FROM generate_series(1, 3)
  )
SELECT * FROM t
UNION ALL
SELECT * FROM t

         x          
--------------------
  0.534150459803641
  0.520092216785997
 0.0735620250925422
  0.534150459803641
  0.520092216785997
 0.0735620250925422

Notar que la consulta WITH fue evaluada solo una vez, por lo que obtuvimos dos conjuntos de los mismos tres valores aleatorios.

Este ejemplo usa WITH RECURSIVE para encontrar todos los subordinados (directos o indirectos) del empleado María, y sus niveles de indirección, desde una tabla que muestra solo los subordinados directos:

WITH RECURSIVE empleado_recursivo(distancia, nombre_empleado, nombre_gerente) AS (
    SELECT 1, nombre_empleado, nombre_gerente
    FROM empleado
    WHERE nombre_gerente = 'María'
  UNION ALL
    SELECT er.distancia + 1, e. nombre_empleado, e. nombre_gerente
    FROM empleado_recursivo er, empleado e
    WHERE er.nombre_empleado = e.nombre_gerente
  )
SELECT distancia, nombre_empleado FROM empleado_recursivo;

Notar la forma típica de consultas recursivas: una condición inicial, seguido por una UNION, seguido por la parte recursiva de la consulta. Estar seguro de que la parte recursiva de la consulta devolverá eventualmente ninguna tupla, o de lo contrario la consulta entrará en un bucle infinito. (Ver  Section 7.8 para más ejemplos.)

Compatibilidad

Por supuesto, la sentencia SELECTes compatible con el estándar SQL. Pero hay algunas extensiones y algunas características faltantes.

Omitiendo clausula FROM

PostgreSQL permite omitir la clausula FROM. Tiene un uso sencillo para computar resultados de expresiones simples:

SELECT 2+2;

 ?column?
----------
        4

Algunas otras bases de datos SQL no pueden hacerlo salvo introduciendo una tabla tonta de una fila desde la cual hacer el SELECT.

Note que si una clausula FROM no es especificada, la consulta no puede referenciar ninguna tabla. Por ejemplo, la siguiente consulta es inválida:

SELECT distribuidores.* WHERE distribuidores.nombre = 'Westward';

Liberaciones de PostgreSQL anteriores a 8.1 aceptarían consultas de esta forma, y agregarían la entrada implícita a la clausula FROM de cada tabla referenciada por la consulta. Este no es más el comportamiento por defecto, porque no cumple con el estándar SQL, y es considerado por muchos como propenso al error. Por compatibilidad con aplicaciones que confian en este comportamiento puede ser habilitada la variable de configuración  add_missing_from.

Omitiendo la palabra claveAS

En el estándar SQL, la palabra clave opcional AS puede ser omitida antes del nombre de columna de salida siempre y cuando el nuevo nombre de columna es un nombre de columna válido (esto es, no ees el mismo que ninguna palabra clave reservada). PostgreSQL es levemente más restrictivo: AS es requerido si el nuevo nombre de clumna coincide con cualquier palabra clave, reservada o no. La practica recomendada es usa AS o encerrar con comillas dobles los nombres de las columnas de salida, para prevenir cualquier posible conflicto contra adiciones de palabras claves futuras.

En los ítems FROM, tanto el estándar y PostgreSQL permiten omitir AS antes de un alias que es una palabra clave no reservada. Pero esto es impráctico para los nombres de columnas de salida, por sus ambigüedades sintácticas.

ONLY y Paréntesis

El estándar SQL requiere paréntesis alrededor del nombre de la tamba despues de ONLY, como en SELECT * FROM ONLY (tab1), ONLY (tab2) WHERE .... PostgreSQL soporta esto también, pero los paréntesis son opcionales. (Este punto aplica de la misma forma a todas las órdenes SQL que soportan la opción ONLY.)

Espacio de nombre disponible a GROUP BY y ORDER BY

En el standar SQL-92, una clausula ORDER BY puede usar solo nombres o números de columnas de salida, mientras que una clausula GROUP BY solo puede usar expresiones en nombres de columnas de entrada. PostgreSQL extendiende cada una de estas clausulas para permitir otras elecciones (pero se usa la interpretación estándar si hay ambiguedades). PostgreSQL también permite que ambas clausulas epsecifique expresiones arbitrarias. Note que los nombres apareciendo en la expresiñon simpre serán tomaos como nombres de columnas de entrada, no de salida.

SQL:1999 y posteriores usan una definición ligeramente diferente que no es completamente compatible hacia atrás con SQL-92. En la mayoría de los casos, sin embargo, PostgreSQL interpretará una expresión ORDER BY o GROUP BY del mismo modo que lo hace SQL:1999.

Restricciones a la clausula WINDOW

El estándar SQL provee opciones adicionales para la clausula_marco de la ventana. PostgreSQL actualmente soporta solo las opciones listadas arriba.

LIMIT y OFFSET

Las clausulas LIMIT y OFFSET son una sintaxis específica de PostgreSQL-specific, también usada por MySQL. El estándar SQL:2008 ha introducido la clausula OFFSET ... FETCH {FIRST|NEXT} ... para la misma funcionalidad, como se muestra arriba en Clausula LIMIT, y esta sintaxis también es usada por IBM DB2. (Aplicaciones escritas para Oracle frecuentemente usan una arreglo provisorio involucrando la columna generada automaticamente rownum, no disponible en PostgreSQL, para implementar los efectos de estas clausulas.)

Clausulas non estándar

La clausula DISTINCT ON no está definida en el estándar SQL.

Comentarios de Usuarios

Comment by MarianoReingart on lun 09 nov 2009 13:47:23 ART

Principales cambios desde la versión 8.0:

  • FOR SHARE apareció en la versión 8.1
  • NULLS { FIRST | LAST } apareció en la versión 8.3
  • [ WITH [ RECURSIVE ] consulta_recursiva [, ...] ], [ WINDOW nombre_ventana AS ( definición_ventana ) [, ...] ] y TABLE { [ ONLY ] nombre_tabla [ * ] | nombre_consulta_with } aparecieron en la versión 8.4

Error: Macro AddComment(None) failed
Error: Insufficient privileges to AddComment