SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] expression [ AS name ] [, ...] [ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ] [ FROM table [ alias ] [, ...] ] [ WHERE condition ] [ GROUP BY column [, ...] ] [ HAVING condition [, ...] ] [ { UNION [ ALL ] | INTERSECT | EXCEPT } select ] [ ORDER BY column [ ASC | DESC | USING operator ] [, ...] ] [ FOR UPDATE [ OF class_name [, ...] ] ] LIMIT { count | ALL } [ { OFFSET | , } start ]
El nombre de una columna de la tabla o una expresión.
Especifica otro nombre para una columna o una expresión que utilice la cláusula AS. Este nombre se utiliza principalmente como etiqueta para la columna de salid. El nombre no puede ser utilizado en las cláusulas WHERE, GROUP BY o HAVING. Sin embargo, puede ser referenciado en cláusulas ORDER BY.
La tabla se crea solamente para esta sesión, y es automáticamente descartada al finalizar la misma.
Si se utiliza la cláusula INTO TABLE, el resultado de la consulta se almacenará en otra tabla con el nombre indicado. La tabla objetivo (new_table) será creada automáticamente y no deberá existir previamente a la utilización de este comando. Consulte el comando SELECT INTO para más información.
Nota: La declaración CREATE TABLE AS también creará una nueva tabla a partir de la consulta.
El nombre de una tabla existente a la que se refiere la cláusula FROM.
Un nombre alternativo para la tabla precedente table. Se utiliza para abreviar o eliminar ambigüedades en uniones dentro de una misma tabla.
Una expresión booleana que da como resultado verdadero o falso (true or false). Consulte la cláusula WHERE.
El nombre de una columna de la tabla.
Una declaración de selección (select) exceptuando la cláusula ORDER BY.
SELECT devuelve registros de una o más tablas. Los candidatos a ser seleccionados son aquellos registros que cumplen la condición especificada con WHERE; si se omite WHERE, se retornan todos los registros. (Consulte Cláusula WHERE.)
DISTINCT elimina registros duplicados del resultado. ALL (predeterminado) devolverá todos los registros, que cumplan con la consulta, incluyendo los duplicados.
DISTINCT ON elimina los registros que cumplen con todas las expresiones especificadas, manteniendo solamente el primer registro de cada conjunto de duplicados. Note que no se puede predecir cuál será "el primer registro" a menos que se utilice ORDER BY para asegurar que el registro eseado es el que efectivamente aparece primero. Por ejemplo:
SELECT DISTINCT ON (location) location, time, report FROM weatherReports ORDER BY location, time DESC;recuperea el reporte de tiempo (weather report) más reciente para cada locación (location). Pero si no se hubiera utilizado ORDER BY para forzar el orden descendente de los valores de fecha para cada locación, se hubiesen recuperado reportes de una fecha impredecible para cada locación.
La cláusula GROUP BY permite al usuario dividir una tabla conceptualmente en grupos. (Consulte Cláusula GROUP BY.)
La cláusula HAVING especifica una tabla con grupos derivada de la eliminación de grupos del resultado de la cláusula previamente especificada. (Consulte Cláusula HAVING.)
La cláusula ORDER BY permite al usuario especificar si quiere los registros ordenados de manera ascendente o descendente utilizando los operadores de modo ASC y DESC. (Consulte Cláusula ORDER BY.)
El operador UNION permite permite que el resultado sea una colección de registros devueltos por las consultas involucradas. (Consulte Cláusula UNION.)
El operador INTERSECT le da los registros comunes a ambas consultas. (Consulte Cláusula INTERSECT.)
El operador EXCEPT le da los registros devueltos por la primera consulta que no se encuentran en la segunda consulta. (Consulte Cláusula EXCEPT.)
La cláusula FOR UPDATE permite a SELECT realizar un bloqueo exclusivo de los registros seleccionados.
La cláusula LIMIT permite devolver al usuario un subconjunto de los registros producidos por la consulta. (Consulte Cláusula LIMIT.)
Usted debe tener permiso de realizar SELECT sobre una tabla para poder leer sus valores. (Consulte las declaraciones GRANT/REVOKE).
La condición opcional WHERE tiene la forma general:
WHERE boolean_exprboolean_expr puede consistir de cualquier expresión cuyo resultado sea un valor booleano. En muchos casos, esta expresión será:
expr cond_op expro
log_op exprdonde cond_op puede ser uno de: =, <, <=, >, >= or <>, un operador condicional como ALL, ANY, IN, LIKE o operador definido localmente, y log_op puede ser uno de: AND, OR, NOT. La comparación devuelve TRUE (verdadero) o FALSE (falso) y todas las instancias serán descartadas si la expresión resulta falsa.
GROUP BY especifica una tabla con grupos derivada de la aplicación de esta cláusula:
GROUP BY column [, ...]
GROUP BY condensará en una sola fila todos aquellos registros que compartan los mismos valores para las columnas agrupadas. Las funciones de agregación, si las hubiera, son computadas a través de todas las filas que conforman cada grupo, produciendo un valor separado por cada uno de los grupos (mientras que sin GROUP BY, una función de agregación produce un solo valor computado a través de todas las filas seleccionadas). Cuando GROUP BY está presente, no es válido hacer referencia a columnas no agrupadas excepto dentro de funciones de agregación, ya que habría más de un posible valor de retorno para una columna no agrupada.
La condición opcional HAVING tiene la forma general:
HAVING cond_exprdonde cond_expr cumple las mismas condiciones que las especificadas para WHERE.
HAVING especifica una tabla con grupos derivada de la eliminación de grupos, del resultado de la cláusula previamente especificada, que no cumplen con cond_expr.
Cada columna referenciada en cond_expr debe referirse precisamente (sin ambigüedades) a una columna de grupo, a menos que la referencia aparezca dentro de una función de agregación.
ORDER BY column [ ASC | DESC ] [, ...]
column puede ser tanto el nombre de una columna como un número ordinal.
Los números ordinales hacen referencia a la posición (de izquierda a derecha) de la columna. Esta característica hace posible definir un orden basado en una columna que no tiene un nombre adecuado. Esto nunca es absolutamente necesario ya que siempre es posible asignar un nombre a una columna calculada utilizando la cláusula AS, por ej.:
SELECT title, date_prod + 1 AS newlen FROM films ORDER BY newlen;
A partir de la versión 6.4 de PostgreSQL, es también posible ordenar, con ORDER BY, según expresiones arbitrarias, incluyendo campos que no aparecen en el resultado de SELECT. Por lo tanto, la siguiente declaración es legal:
SELECT name FROM distributors ORDER BY code;
Opcionalmente una puede agregar la palabra clave DESC (descendente) o ASC (ascendente) luego del nombre de cada columna en la cláusula ORDER BY. Si no se especifica, se asume ASC de forma predeterminada. Alternativamente, puede indicarse un nombre de operador de orden específico. ASC es equivalente a USING '<' y DESC es equivalente a USING '>'.
table_query UNION [ ALL ] table_query [ ORDER BY column [ ASC | DESC ] [, ...] ]donde table_query especifica cualquier declaración SELECT sin la cláusula ORDER BY.
El operador UNION permite que el resultado sea una colección de registros devueltos por las consultas involucradas. Los dos SELECTs que representan los dos operandos directos de la UNION deben producir el mismo número de columnas, y las columnas correspondientes deben ser de tipos de datos compatibles.
De forma predeterminada, el resultado de UNION no contiene registros duplicados a menos que se especifique la cláusula ALL.
Si se utilizan varios operadores UNION en la misma declaración SELECT se evalúan de izquierda a derecha. Note que la palabra clave ALL no es global, siendo aplicada solamente al par de tablas de resultado actual.
table_query INTERSECT table_query [ ORDER BY column [ ASC | DESC ] [, ...] ]donde table_query especifica cualquier expresión SELECT sin la cláusula ORDER BY.
El operador INTERSECT le da los registros comunes a ambas consultas. Los dos SELECTs que representan los operandos directos de la intersección deben producir el mismo número de columnas, y las columnas correspondientes deben ser de tipos de datos compatibles.
Si se utilizan varios operadores INTERSECT en la misma declaración SELECT se evalúan de izquierda a derecha, a menos que se utilicen paréntesis para modificar esto.
table_query EXCEPT table_query [ ORDER BY column [ ASC | DESC ] [, ...] ]donde table_query especifica cualquier expresión SELECT sin la cláusula ORDER BY.
El operador EXCEPT le da los registros devueltos por la primera consulta pero no por la segunda. Los dos SELECTs que representan los operandos directos de la intersección deben producir el mismo número de columnas, y las columnas correspondientes deben ser de tipos de datos compatibles.
Si se utilizan varios operadores INTERSECT en la misma declaración SELECT se evalúan de izquierda a derecha, a menos que se utilicen paréntesis para modificar esto.
LIMIT { count | ALL } [ { OFFSET | , } start ] OFFSET startdonde count especifica el máximo número de registros a devolver y start especifica el número de registros a saltear antes de empezar a devolver registros.
LIMIT le permite recuperar sólo una porción de los registros que se generan por el resto de la consulta. Si se especifica un número límite, no se devolverán más registros que esa cantidad. Si se da un valor de desplazamiento, esa cantidad de registros será salteada antes de comenzar a devolver registros.
Cuando se utiliza LIMIT es una buena idea utilizar la cláusula ORDER BY para colocar los registros del resultado en un orden único. De otra forma obtendrá un subconjunto impredecible de los registros de la consulta --- tal vez esté buscando los registros del décimo al vigésimo, ¿pero del décimo al vigésimo en qué orden? Usted no conoce el orden a menos que utilice ORDER BY.
Ya en Postgres 7.0, el optimizador de consultas toma en cuenta a LIMIT cuando genera un plan de consulta, así que es muy factible que usted obtenga diferentes planes (abarcando diferentes criterios de ordenamiento de registros) dependiendo de los valores dados a LIMIT y OFFSET. Por lo tanto, utilizar diferentes valores para LIMIT/OFFSET para seleccionar diferentes subconjuntos del resultado de una consulta, provocará resultados inconsistentes a menos que usted se asegura un resultado predecible ordenando con ORDER BY. Esto no es un bug; es una consecuencia inherente al hecho de que SQL no establece ningún compromiso de entregar los resultados de una consulta en un orden en particular a menos que se utilice ORDER BY para especificar un criterio de orden explícitamente.
Para unir la tabla films con la tabla distributors:
SELECT f.title, f.did, d.name, f.date_prod, f.kind FROM distributors d, films f WHERE f.did = d.did title |did|name | date_prod|kind -------------------------+---+----------------+----------+---------- The Third Man |101|British Lion |1949-12-23|Drama The African Queen |101|British Lion |1951-08-11|Romantic Une Femme est une Femme |102|Jean Luc Godard |1961-03-12|Romantic Vertigo |103|Paramount |1958-11-14|Action Becket |103|Paramount |1964-02-03|Drama 48 Hrs |103|Paramount |1982-10-22|Action War and Peace |104|Mosfilm |1967-02-12|Drama West Side Story |105|United Artists |1961-01-03|Musical Bananas |105|United Artists |1971-07-13|Comedy Yojimbo |106|Toho |1961-06-16|Drama There's a Girl in my Soup|107|Columbia |1970-06-11|Comedy Taxi Driver |107|Columbia |1975-05-15|Action Absence of Malice |107|Columbia |1981-11-15|Action Storia di una donna |108|Westward |1970-08-15|Romantic The King and I |109|20th Century Fox|1956-08-11|Musical Das Boot |110|Bavaria Atelier |1981-11-11|Drama Bed Knobs and Broomsticks|111|Walt Disney | |Musical
Para sumar la columna len (duración) de todos los filmes y agrupar los resultados según la columna kind (tipo):
SELECT kind, SUM(len) AS total FROM films GROUP BY kind; kind |total ----------+------ Action | 07:34 Comedy | 02:58 Drama | 14:28 Musical | 06:42 Romantic | 04:38
Para sumar la columna len de todos los filmes, agrupar los resultados según la columna kind y mostrar los totales de esos grupos que sean menores a 5 horas:
SELECT kind, SUM(len) AS total FROM films GROUP BY kind HAVING SUM(len) < INTERVAL '5 hour'; kind |total ----------+------ Comedy | 02:58 Romantic | 04:38
Los siguientes dos ejemplos muestran maneras idénticas de ordenar los resultados individuales de acuerdo con los contenidos de la segunda columna (name):
SELECT * FROM distributors ORDER BY name; SELECT * FROM distributors ORDER BY 2; did|name ---+---------------- 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
Este ejemplo muestra cómo obtener la union de las tablas distributors y actors, restringiendo los resultados a aquellos que comienzan con la letra W en cada tabla. No se quieren duplicados, así que la palabra clave ALL se omite.
-- distributors: actors: -- did|name id|name -- ---+------------ --+-------------- -- 108|Westward 1|Woody Allen -- 111|Walt Disney 2|Warren Beatty -- 112|Warner Bros. 3|Walter Matthau -- ... ... SELECT distributors.name FROM distributors WHERE distributors.name LIKE 'W%' UNION SELECT actors.name FROM actors WHERE actors.name LIKE 'W%' name -------------- Walt Disney Walter Matthau Warner Bros. Warren Beatty Westward Woody Allen
Postgres permite omitir la cláusula FROM de una consulta. Esta característica fue conservada del lenguaje original de consulta PostQuel:
SELECT distributors.* WHERE name = 'Westwood'; did|name ---+---------------- 108|Westward
En el estándar SQL92, la palabra clave opcional "AS" es totalmente prescindible y puede ser omitida sin afectar el significado. El analizador sintáctico de Postgres requiere la presencia de esta palabra cuando se renombran columnas debido a las características de extensibilidad de tipos que pueden llevar a interpretaciones ambiguas en este contexto.
DISTINCT ON no es parte de SQL92. Tampoco los son LIMIT y OFFSET.