sqlite.h


SELECT

Sintaxis SELECT
SELECT
Núcleo de SELECT
Núcleo de SELECT
Columna de resultado
Columna de resultado
Fuente de JOIN
Fuente de JOIN
Fuente única
Fuente única
Operador join
Operador join
Restricción de join
Restricción de join
Término de ordenación
Término de ordenación
Operador de composición
Operador de composición

La sentencia SELECT se usa para hacer consultas en la base de datos. El resultado de un SELECT es cero o más filas de datos donde cada fila tiene un número fijo de columnas.

La sentencia SELECT es la más compleja del lenguaje SQL. Para que la siguiente explicación sea más sencilla, algunos de los pasajes a continuación describen el modo en que se determinan los datos devueltos por una sentencia SELECT como una serie de pasos. Es importante tener en mente que esto es puramente ilustrativo - en la práctica ni SQLite ni nigún otro motor de base de datos tiene por que seguir ni este u otros procesos especificos.

Procesamiento de una selección sencilla

La sintaxis para una sentencia SELECT simple se muestra en el diagrama de sintaxis "Nucleo de SELECT". La generación de los resultados de una sentencia SELECT se presenta como un proceso con los cuatro pasos siguientes:

  1. El proceso de la cláusula FROM: determina los datos de entrada para el SELECT. De forma implícita, los datos de entrada consisten en una fila con 0 columnas (si no aparece la cláusula FROM) o se determina mediante el análisis de la especificación de la "fuente de JOIN" que sigue a una cláusula FROM explícita.
  2. El proceso de la cláusula WHERE: los datos de entrada se filtran usando la expresión de la cláusula WHERE.
  3. El proceso de GROUP BY, HAVING y la expresion "columna de resultado": el conjunto de filas de resultado se calcula mediante el agregado de los datos conforme a cualquier cláusula GROUP BY y calculando las expresiones del conjunto de resultados para las filas del conjunto de datos filtrados.
  4. El proceso de las palabras clave DISTINCT/ALL: si la consulta es del tipo SELECT DISTINCT, las filas repetidas son eliminadas del conjunto de resultados.

Existen dos tipos de sentencias SELECT sencillas - consultas agregadas y no agreagadas. Una sentencia SELECT sencilla es agregada si en ella aparece una cláusula GROUP BY o una o más funciones agregadas en el conjunto de resultados. En otro caso, si la sentencia SELECT sencilla no contiene funciones agregadas o la cláusula GROUP BY, se trata de una consulta no agregada.

1. Determinación de los datos de entrada (proceso de la cláusula FROM)

Los datos de entrada usados por una consulta SELECT sencilla es un conjunto de N filas, cada una con M columnas.

Si se omite la cláusula FROM de una sentencia SELECT sencilla, entonces los datos de entrada son simplemente una única fila con cero columnas (es decir, N=1 y M=0).

Si se especifica una cláusula FROM, los datos de una consulta SELECT sencilla provienen de una o más tablas o subconsultas (sentencias SELECT entre paréntesis) especificadas a continuación de la palabra clave FROM. Una subselección especificada en "fuente de JOIN" que sigue a la cláusula FROM en una sentencia SELECT sencilla es manipulada como si se tratase de una tabla que contenga los datos devueltos por la ejecución de la sentencia de subselección. Cada columna del conjunto de datos de la subselección hereda la secuencia de ordenamiento y afinidad de la expresión correspondiente a la sentencia de subselección.

Si únicamente hay una tabla en la "fuente de JOIN" que sigue a la cláusula FROM, entonces los datos de entrada usados por la sentencia SELECT es el contenido de la tabla indicada. Si hay más de una tabla, entonces el contenido de cada tabla indicada se une (join) en un conjunto de datos para que la sentencia SELECT sencilla opere con él. El modo en que los datos se combinen con exactitud depende del operador de unión y de las restricciones de unión específicas usadas para conectar las tablas o subconsultas juntas.

Todas las combinaciones de tablas en SQLite se basan en productos cartesianos de los conjuntos de datos izquierdo y derecho. Las columnas del conjunto de datos del producto cartesiano son, en ese orden, todas las columnas del conjunto de datos izquierdo seguidos por todas las columnas del conjunto de datos derecho. En el conjunto de datos del producto cartesiano habrá una fila formada por cada una de las combinaciones de las filas del conjunto izquierdo con cada una de las del conjunto derecho. En otras palabras, si el conjunto de datos derecho consiste en Ni filas de Mi columnas, y el derecho de Nd filas de Md columnas, el producto cartesiano es un conjunto de datos de Ni x Nd filas, cada una con Mi x Md columnas.

Si el operador de combinación es "CROSS JOIN", "INNER JOIN", "JOIN" o una coma (",") y no hay una cláusula ON o USING, entonces el resultado de la combinación es sencillamentel producto cartesiano de los conjuntos de datos izquiedo y derecho. No existe diferencia entre los operadores "INNER JOIN", "JOIN" y ",". El operador de combinación "CROSS JOIN" produce los mismos datos que los operadores "INNER JOIN", "JOIN" y ",", pero es manejado de un modo algo diferente por el optimizador de consultas. En caso contrario, el producto cartesiano es modificado de acuerdo con uno o más de los siguientes puntos:

  • Si existe una cláusula ON, entonces la expresión se evalúa pra cada fila del producto cartesiano como una expresión booleana. Todas las filas para las que la expresión evaluada sea falsa se excluyen del conjunto de resultados.
  • Si se especifica una cláusula USING como parte de la restricción de combinación, entonces cada una de los nombres de columna especificados deben existir en los conjuntos de datos izquierdo y derecho del operador de combinación. Para cada pareja de columnas con el mismo nombre, la expresión "i.x = d.X" es evaluada para cada fila del producto cartesiano como una expresión booleana. Todas las filas para las que una o más expresiones evaluadas sean falsas se excluyen del conjunto de resultados. Cuando se comparan valores como un resultado de una cláusula USING, se aplican las reglas normaes para manipulación de afinidadas, secuencias de ordenamiento y valores NULL. La columna del conjunto de datos izquierdo respecto al operador de combinación se considera como el valor a la izquierda del operador de comparación (=) para los fines de secuencias de comparación y precedencia de afinidad.
  • Para cada par de columnas identificadas por la cláusula USING, la columna del conjunto de datos derecho se omite del conjunto de datos resultante. Esta es la única diferencia entre la cláusula USING y su restricción ON equivalente.
  • Si se añade la palabra clave NATURAL a cualquiera de los operadores de combinación, entonces se añade una cláusula USING implícita a las restricciones de combinación. La cláusula USING implícita contiene cada uno de los nombre de columna que aparecen tanto en el conjunto de datos izquierdo como en el derecho. Si los conjuntos de datos izquiedo y derecho no tienen nombres de columnas comunes, entonces la palabra clave NATURAL no tiene efecto sobre los resultados de la combinación. No se añade ninguna cláusula USING ni OR a una combinación que especifique la palabra clave NATURAL.
  • Si el operador de combinación es un "LEFT JOIN" o "LEFT OUTER JOIN", entonces después de aplicar las cláusulas ON o USING, se añade una fila extra a la salida por cada fila en el conjunto de datos a la izquierda a la que no correspondan filas en todo el conjunto de datos compuesto (si existe). Las filas añadidas contienen valores NULL en las columnas que normalmente contendrían los valores copiados del conjunto de datos de entrada de la derecha.

Cuando se combinan más de dos tablas como parte de una cláusula FROM, los operadores de combinación se procesan de izquierda a derecha. En otras palabras, la cláusula FROM (A join-op-1 B join-op-2 C) se procesa como ((A join-op-1 B) join-op-2 C).

2. El filtrado de la cláusula WHERE

Si se especifica una cláusula WHERE, la expresión WHERE se evalúa para cada fila de los datos de entrada como una expresión booleana. Todas las filas para las que la expresión de la cláusula WHERE se evalúen como falsas son eliminadas del conjunto de datos antes de continuar.

3. Generación de las filas del conjunto de resultados

Una vez que los datos de entrada del la cláusula FROM han sido filtrados por la expresión de la cláusula WHERE (si existe), se calculan las filas del conjunto de resultados para la selección simple. El modo exacto en que se hace esto depende de si la selección simple es o no una consulta agregada, y si se ha especificado o no una cláusula GROUP BY.

La lista de expresiones entre las palabras clave SELECT y FROM se conoce como la lista de expresión de resultado. Si una expresión de resultado es la expresión especial "*" entonces todas las columnas en los datos de entrada se sustituyen por esta expresión. Si la expresión es el alias de una tabla o subconsulta en la cláusula FROM seguda por ".*" entonces todas las columnas de la tabla o subconsulta especificada son sustituidas por la expresión sencilla. Se considera un error el uso de una expresión "*" o "alias.*" en un contexto que no sea una lista de expresión de resultado. También es un error usar una expresión "*" o "alias.*" en una consulta SELECT simple que no tenga una cláusula FROM.

El número de columnas en las filas retornadas por una sentencia SELECT simple es igual al número de expresiones en la lista de expresión de resultado después de la sustitución de las expresiones * y alias.*. Cada fila de resultado se calcula mediante la evaluación de las expresiones en la lista de expresión de resultado con respecto a una fila simple de los datos de entrada o, para consultas agregadas, con respecto al grupo de filas.

  • Si la sentencia SELECT es una consulta no agragada, entonces cada expresión en la lista de expresión de resultado se evalúa para cada fila en el conjunto de datos filtrados por la cláusula WHERE.
  • Si la sentencia SELECT es una consulta agregada sin la cláusula GROUP BY, entonces cada expresión agregada en el conjunto de resultados se evalúa una vez para todo el conjunto de datos. Cada expresión no agregada en el conjunto de resultados se evalúa una vez para una fila del conjunto de datos seleccionada de forma arbitraria. La misma fila seleccionada arbitrariamente se usa para cada expresión no agregada. O, si el conjunto de datos no contiene filas, entonces cada expresión no agregada se evalúa en una fila compuesta únicamente por valores NULL.
  • La fila simple de los datos del conjunto de resultados creada por la evaluación de las expresiones agregadas y no agregadas, forma el resultado de una consulta agregada sin la cláusula GROUP BY. Una consulta agregada sin la cláusula GROUP BY siempre devuelve una fila de datos, aunque los datos de entrada no contengan ninguna fila.
  • Si la sentencia SELECT es una consulta agregada con una cláusula GROUP BY, entonces cada una de las expresiones especificadas como parte de la cláusula GROUP BY se evalúa para cada fila del conjunto de datos. Cada fila es entonces asignada a un "grupo" basado en los resultados; las filas para las que los resultados de la evaluación de las expresiones GROUP BY son los mismos, son asignados al mismo grupo. A los efectos de las filas agrupadas, los valores NULL se consideran iguales. Se aplican las reglas habituales para seleccionar una secuencia de ordenamiento con la que se comparan valores de texto cuando se evalúan expresiones en una cláusula GROUP BY. Las expresiones en la cláusula GROUP BY no tienen por qué ser expresiones que aparezcan en el resultado. Las expresiones en una cláusula GROUP BY no pueden ser expresiones agregadas.
  • Si se especifica una cláusula HAVING, se evalúa una vez para cada grupo de filas. Si el resultado de la evaluación de la cláusula HAVING es falsa, el grupo se descarta. Si la cláusula HAVING es una expresión agregada, se evalúa a través de todas las filas del grupo. Si una cláusula HAVING es una expresión no agregada, se evalúa con respecto a una fila del grupo arbitrariamente elegida. La expresión HAVING se puede referir a valores, e incluso a funciones, que no estén en los resultados.
  • Cada expresión en el conjunto de resultados es entonces evaluada una vez para cada grupo de filas. Si la expresión es una expresión agregada, se evalúa a través de todas las filas del grupo. En caso contrario, se evalúa en una sola fila del grupo elegida arbitrariamente. Si hay más de una expresión no agregada en el conjunto de resultados, entonces todas las expresiones se evalúan para la misma fila.
  • Cada grupo de filas del conjunto de datos de entrada aporta una sola fila al conjunto de resultados. Sin perjuicio del filtrado asociado a la palabra clave DISTINCT, el número de filas devuelto por una consulta agregada con la cláusula GROUP BY es el mismo que el número de grupos de filas producido por la aplicación de las cláusulas GROUP BY y HAVING para el conjunto de datos de entrada filtrado.

4. Eliminación de filas duplicadas (procesado de DISTINCT)

Una de las palabras clave ALL o DISTINCT puede seguir a la palabra clave SELECT en una sentencia de selección simple. Si la selección simple es un SELECT ALL, entonces se devuelven las filas del conjunto de resultado completo. Si no están presentes ni ALL ni DISTINCT, entonces el comportamiento es el mismo que si se se hubiera especificado ALL. Si la selección simple es un SELECT DISTINCT, entonces las filas duplicadas se eliminan del conjunto de resultados antes de ser devuelgo. A los efectos de detectar filas duplicadas, dos valores NULL se consideran iguales. Se aplican las reglas habituales para seleccionar una secuencia de ordenamiento en las comparaciones de valores de texto.

Sentencias de selección compuestas

Dos o más sentencias SELECT simples pueden estar conectadas juntas para formar un SELECT compuesto usando el operador UNION, UNION ALL, INTERSECT o EXCEPT. En un SELECT compuesto, todas las selecciones que lo componen deben retornar el mismo número de columnas. Dado que los componentes de un SELECT compuesto deben ser sentencias SELECT simples, no deben contener cláusulas ORDER BY o LIMIT. Las cláusulas ORDER BY y LIMIT sólo pueden aparecer al final del SELECT compuesto completo.

Un SELECT compuesto creado usando el operador UNION ALL devuelve todas las filas del SELECT a la izquierda del operador UNION ALL, y todas las filas del SELECT a la derecha de él. El operador UNION trabaja del mismo modo que UNION ALL, excepto que se eliminan las filas duplicadas del conjunto de resultados final. El operador INTERSECT devuelve la intersección de los resultados de los SELECT izquierdo y derecho. El operador EXCEPT retorna el subconjunto de filas devuelto por el SELECT izquierdo que no son devueltos también por el SELECT derecho. Las filas duplicadas son eliminadas de los resultados de los operadores INTERSECT y EXCEPT antes de que el conjunto de resultados sea devuelto.

A efectos de determinar las filas duplicadas para los resultados de operadores SELECT compuestro, los valores NULL se consideran iguales a cualquier otro valor NULL y distintos de todos los valores no NULL. La secuencia de ordenamiento usada para comparar dos valores de texto se determina como si las columnas izquierda y derecha de las sentencias SELECT estuvieran a la izquierda y derecha del operador de igualdad (=), excepto que la mayor prioridad no se asigna una secuencia de ordenamiento especificada por el operador sufijo COLLATE. No se aplican transformaciones de afinidad a ningún valor cuando se comparan filas como parte de un SELECT compuesto.

Cuando tres o más SELECT simples se conectan dentro de un SELECT compuesto, se agrupan de izquierda a derecha. En otras palabras, si "A", "B" y "C" son sentencias SELECT simples, (A op B op C) se procesan como ((A op B) op C).

Las cláusulas ORDER BY y LIMIT/OFFSET

Si una sentencia SELECT que devuelva más de una fila no tiene una cláusula ORDER BY, el orden en el que se devuelven las filas es indefinido. O, si una sentencia SELECT tiene una cláusula ORDER BY, entonces la lista de expresiones asociada al ORDER BY determina el orden en que las filas se devuelven al usuario. Las filas son ordenadas primero basándose en el resultado de evaluar la expresión más a la izquierda en la lista ORDER BY, a continuación se pasa al siguiente nivel mediante la evaluación de la siguiente expresión más a la izquierda y así sucesivamente. El orden en que se retornan dos filas para las que todas las expresiones ORDER BY evaluadas tengan valores iguales es indeterminado. Cada expresión ORDER BY puede estar seguida opcionalmente por una palabra clave ASC (los valores más pequeños son retornados antes) o DESC (los valores mayores son retornados antes). Si no se especifica ni ASC ni DESC, las filas son ordenadas en orden ascendente (valores pequeños primero) por defecto.

Cada expresión ORDER BY se procesa como sigue:

  1. Si la expresión ORDER BY es una constante entera K entonces la expresión se considera un alias para la columna K del conjunto de resultados (las columnas se numeran de izquierda a derecha empezando en 1).
  2. Si la expresión ORDER BY es un identificador que corresponde al alias de una de las columnas de salida, entonces la expresión se considera, efectivamente, como un alias para esa columna.
  3. En cualquier otro caso, si la expresión ORDER BY es cualquier otra expresión, se evalúa y el valor retornado se usa para ordenar las filas de salida. Si la sentencia SELECT es una selección simple, entonces un ORDER BY puede contener cualquier expresión arbitraria. Sin embargo, si se trata de una selección compuesta, las expresiones ORDER BY que no sean alias de columnas de salida deben ser exactamente expresiones usadas para una columna de salida.

A los efectos de ordenar filas, los valores se comparas del mismo modo que se comparan expresiones. La secuencia de ordenamiento usada para comparar dos valores de texto se determina como sigue.

  1. Si la expresión ORDER BY se asigna a una secuencia de ordenamiento usando el operador sufijo COLLATE, entonces se usa la secuencia de ordenamiento especificada.
  2. De lo contrario, si la expresión ORDER BY es un alias para una expresión que ha sido asignada a una secuencia de ordenamiento usando el operador COLLATE, entonces se usa la secuencia asignada al alias.
  3. De lo contrario, si la expresión ORDER BY es una columna o un alias de una expresión que es una columna, entonces se usa la secuencia de ordenación por defecto para esa columna.
  4. De lo contrario, se usa la secuencia de ordenación BINARY.

En una sentencia de selección compuesta, todas las expresiones ORDER BY son manipuladas como alias para una de las columnas del resultado de la selección compuesta. Si una expresión ORDER BY no es un alias entero, entonces SQLite busca en el SELECT más a la izquierda en la selección compuesta una columna que coincida con cualquiera de las reglas anteriores, segunda o tercera. Si se encuentra una coincidencia, la búsqueda se detiene y la expresión se manipula como un alias para esa columna de resultado. En otro caso, se intenta con el siguiente SELECT a la derecha, y sucesivamente. Si no se puede encontrar una expresión coincidente en las columnas de resultados de ninguno de los SELECT, se produce un error. Cada término de la cláusula ORDER BY se procesa separadamente y puede ser comparado con las columnas de resultads de las distintas sentencias SELECT en la composición.

La cláusula LIMIT se usa para establecer un límite superior en el número de filas retornadas por una sentencia SELECT. Cualquier expresión escalar se puede usar en la cláusula LIMIT, siempre y cuando se evalúe como un entero o un valor que pueda convertirse sin pérdida a un entero. Si la expresión se evalúa como un valor NULL o cualquier otro valor que no se pueda convertir sin pérdida a un entero, se retorna un error. Si la expresión LIMIT se evalúa a un valor negativo, entonces no hay un límite superior en el número de filas retornadas. En caso contrario, el SELECT retorna sólo las primeras N filas del conjunto de resultados, donde N es el valor resultado de la evaluación de la expresión LIMIT. O, si la sentencia SELECT debe retornar menos de N filas sin la cláusula LIMIT, entonces se devuelve el conjunto de resultados completo.

La expresión asociada a la cláusula opcional OFFSET que puede seguir a la cláusula LIMIT también debe evaluarse como un entero, o como un valor que pueda ser convertido a un entero sin pérdida. Si una expresión tiene una cláusula OFFSET, entonces las primeras M filas del conjunto de resultados devueltos por la sentencia SELECT son omitidas y las siguientes N filas son devueltas, donde M y N son los valores evaluados de las cláusulas OFFSET y LIMIT, respectivamente. O, si el SELECT debe retornar menos de M+N filas si no tuviera la cláusula LIMIT, entonces las M primeras filas se omiten y las filas restantes (si existen) se devuelven. Si la cláusula OFFSET se evalúa como un valor negativo, los resultados son los mismos que si se hubiera evaluado a cero.

En lugar de una cláusula OFFSET separada, la cláusula LIMIT puede especificar dos expresiones escalares separadas con una coma. En ese caso, la primera expresión se usa como la expresión del OFFSET y la segunda como la del LIMIT. Esto es lo contrario a lo intuitivo, ya que cuando se usan las dos cláusulas, la de OFFSET es la segunda. Esto es intencionado y maximiza la compatibilidad con otros sistemas de bases de datos SQL.