mysql.h


SELECT

SELECT 
      [ALL | DISTINCT | DISTINCTROW]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
   select_expr,...
   [INTO OUTFILE 'file_name' export_options]
    | INTO DUMPFILE 'file_name']
   [FROM table_references
      [WHERE where_definition]
      [GROUP BY {col_name | expr | position} 
        [ASC | DESC], ... [WITH ROLLUP]]
      [HAVING where_definition]
      [ORDER BY {col_name | expr | position} 
        [ASC | DESC] ,...]
      [LIMIT {[offset,] row_count | row_count OFFSET offset}]
      [PROCEDURE procedure_name(argument_list)]
      [FOR UPDATE | LOCK IN SHARE MODE]]

SELECT se usa para recuperar filas selecionadas de una o más tablas. El soporte para sentencias UNION y subconsultas está disponible a partir de MySQL 4.0 y 4.1, respectivamente.

  • Cada select_expr indica una columna que se quiere recuperar.
  • table_references indica la tabla o tablas de las que se recuperan filas. Su sintaxis se describe en JOIN.
  • where_definition consiste de la palabra clave WHERE seguida por una expresión que indica la condición o condiciones que las filas deben satisfacer para ser seleccionadas.

SELECT puede usarse también para recuperar filas calculadas sin referencia a ninguna tabla. Por ejemplo:

mysql> SELECT 1 + 1;
         -> 2

Todas las cláusulas usadas deben darse en el mismo orden exacto que se muestra en la descripción de la sintaxis. Por ejemplo, la cláusula HAVING debe estar después de cualquier cláusula GROUP BY y antes de cualquier cláusula ORDER BY.

  • Una select_expr puede usar alias mediante AS nombre_alias. El alias se usa como un nombre de columna en expresiones y puede usarse por las cláusulas ORDER BY o HAVING. Por ejemplo:
  • mysql> SELECT CONCAT(apellido,', ',nombre) AS nombre_completo
        FROM mitabla ORDER BY nombre_completo;
  • La palabra clave AS es opcional cuando se define un alias en una select_expr. El ejemplo anterior se puede escribir como:
  • mysql>  SELECT CONCAT(apellido,', ',nombre) nombre_completo
        FROM mitabla ORDER BY nombre_completo;
  • Debido a que AS es opcional, puede ocurrir un problema si se olvida la coma entre dos select_expr: MySQL interpreta el segundo como un alias. Por ejemplo, en la sentencia siguiente, columnab se trata como un alias:
  • mysql> SELECT columna columnab FROM mitabla;
  • No está permitido usar un alias en una cláusula WHERE, porque el valor de la columna puede que no esté determinado todavía cuando la cláusula WHERE es ejecutada.
  • La cláusula FROM table_references indica las tablas desde las que se recuperarán filas. Si se nombra más de una tabla, se realiza una unión (JOIN). Para cada tabla especificada, opcionalmente se puede especificar un alias.
    table_name [[AS] alias] 
        [[USE INDEX (key_list)] 
          | [IGNORE INDEX (key_list)] 
          | FORCE INDEX (key_list)]]
    El uso de USE INDEX, IGNORE INDEX, FORCE INDEX para proporcionar al optimizador pistas sobre cómo elegir índices se describe en la sintaxis de JOIN. En MySQL 4.0.14, se puede usar SET max_seeks_for_key=value como una alternativa para forzar a MySQL a elegir un recorrido secuencial por clave en lugar de un recorrido secuencial de la tabla.
  • Desde la versión 3.23.12 de MySQL, se pueden obtener pistas sobre qué índice debe usar
  • Se puede hacer referencia a una tabla con el nombre de la tabla "tbl_name" (dentro de la base de datos actual), o con la especificación completa incluyendo la base de datos "dbname.tbl_name". También se puede hacer referencia a una columna como "col_name", "tbl_name.col_name", o "db_name.tbl_name.col_name". No es necesario especificar un prefijo "tbl_name" o "db_name.tbl_name" para referenciar una columna en una sentencia SELECT a no ser que la referencia pueda resultar ambigua.
  • Desde la versión 4.1.0, se puede especificar DUAL como nombre de una tabla vacía, en situaciones en las que no haya tablas definidas.
    mysql> SELECT 1 + 1 FROM DUAL;
             -> 2
    Esta es una característica añadida sólo por compatibilidad. Ciertos servidores requieren esa sintaxis.
  • Se puede definir un alias a una referencia de tabla mediante tbl_name [AS] alias_name:
  • mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
        ->        WHERE t1.name = t2.name;
    mysql> SELECT t1.name, t2.salary FROM employee t1, info t2
        ->        WHERE t1.name = t2.name;
  • En la cláusula WHERE, se puede usar cualquiera de las funciones soportadas por MySQL, excepto funciones las de reunión (resumen).
  • Las columnas seleccionadas pueden ser referenciadas a cláusulas ORDER BY y GROUP BY usando nombres de columna, alias de columna o posiciones de columna. Las posiciones de columna son enteros que empiezan en 1:
    mysql> SELECT college, region, seed FROM tournament
        ->        ORDER BY region, seed;
    mysql> SELECT college, region AS r, seed AS s FROM tournament
        ->        ORDER BY r, s;
    mysql> SELECT college, region, seed FROM tournament
        ->        ORDER BY 2, 3;
    Para ordenar en orden inverso se añade la palabra clave DESC (descendente) al nombre de la columna en la cláusula ORDER BY en la que se está ordenando. Por defecto el orden es ascendente, pero puede ser especificado explícitamente por la palabra clave ASC. El uso de posiciones de columna está desaconsejado ya que esa sintaxis ha sido eliminada de SQL estándar.
  • Si se usa GROUP BY, la filas de salida serán ordenadas de acuerdo con el GROUP BY como si se hubiese usado ORDER BY sobre los campos del GROUP BY. MySQL ha extendido la cláusula GROUP BY a partir de la versión 3.23.34 de modo que se puede especificar también ASC y DESC después de los nombres de columna en la cláusula:
  • SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
  • MySQL ha extendido el uso de GROUP BY para permitir seleccionar campos que no se han mencionado en la cláusula GROUP BY. Si no se obtiene el resultado esperado de la consulta, leer la descripción de GROUP BY.
  • A partir de MySQL 4.1.1, GROUP BY permite el modificador WITH ROLLUP.
  • La cláusula HAVING se aplica cerca del final, justo antes de que los resultados se envíen al cliente, sin optimizaciones. (LIMIT se aplica después de HAVING). Antes de MySQL 5.0.2, una cláusula HAVING se puede referir a cualquier columna o alias en la select_expr de lista SELECT o en las subconsultas exteriores, y a las funciones agregadas. SQL estándar requiere que HAVING debe hacer deferencia sólo a columnas en la cláusula GROUP BY o columnas usadas en funciones agregadas. Para permitir ambos comportamientos, el de SQL estándar y el específico de MySQL, que permite referirse a columnas en la lista SELECT, a partir de MySQL 5.0.2 se permite que HAVING se refiera a columnas en la lista SELECT, columnas en la cláusula GROUP BY, columnas en subconsultas exteriores, y a funciones agregadas. Por ejemplo, la siguiente sentencia funciona en MySQL 5.0.2, pero produce un error en versiones anteriores:
    mysql> SELECT COUNT(*) FROM t GROUP BY col1 HAVING col1 = 2;
    Si la cláusula HAVING se refiere a una columna que es ambigua, se produce un aviso. En la sentencia siguiente, col2 es ambiguo porque se usa tanto como un alias y como un nombre de columna:
    mysql> SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
    Se da preferencia al comportamiento de SQL estándar, así que si un nombre de columna en un HAVING se usa en un GROUP BY y como un alias de columna en la lista de columnas de salida, se toma preferentemente la columna en GROUP BY.
  • No se debe usar HAVING para items para los que se pueda usar una cláusula WHERE. Por ejemplo, no escribir esto:
    mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;
    Sino esto:
  • mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;
  • La cláusula HAVING se puede referir a funciones agregadas, a las que una cláusula WHERE no puede:
    mysql> SELECT user, MAX(salary) FROM users
        ->     GROUP BY user HAVING MAX(salary)>10;
    Sin embargo, esto no funciona en servidores antiguos de MySQL (anteriores a la versión 3.22.5). En su lugar, se puede usar un alias de columna en la lista SELECT y referirse al alias en la cláusula HAVING:
  • mysql> SELECT user, MAX(salary) AS max_salary FROM users
        ->     GROUP BY user HAVING max_salary>10;
  • La cláusula LIMIT puede ser usada para limitar a que el número de filas devuelto por la sentencia SELECT. LIMIT toma uno o dos argumentos numéricos, que deben ser constantes enteras. Con dos argumentos, el primero especifica el desplazamiento de la primera fila a devolver, el segundo especifica el máximo número de filas a devolver. El desplazamiento de la fila inicial es 0 (no 1):
    mysql> SELECT * FROM table LIMIT 5,10;  # Recupera filas 6-15
    Por compatibilidad con PostgreSQL, MySQL también soporta la sintaxis: LIMIT row_count OFFSET offset. Para recuperar todas las filas a partir de un desplazamiento concreto hasta el final del conjunto de resultados, se puede usar un número muy grande como segundo parámetro. Esta sentencia recupera todas las filas a partir de la 96 hasta el final:
    mysql> SELECT * FROM table LIMIT 95,18446744073709551615;
    Con un argumento, el valor especifica el número de filas a devolver desde el principio del conjunto de resultados.
    mysql> SELECT * FROM table LIMIT 5;     # Retrieve first 5 rows
    En otras palabras, LIMIT n equivale a LIMIT 0,n.
  • El formato SELECT ... INTO OUTFILE 'file_name' de SELECT escribe las filas seleccionadas en un fichero. El fichero se crea en el host del servidor, de modo que se debe poseer el privilegio FILE para usar esta sintaxis.El fichero no debe existir previamente, entre otras cosas, esto previene que tablas de la base de datos y otros ficheros como `/etc/passwd' puedan ser destruidos. La sentencia SELECT ... INTO OUTFILE está pensada para permirtir un volcado muy rápido de una tabla en la máquina del servidor. Si se quiere crear el fichero resultado en algún otro host, no se puede usar SELECT ... INTO OUTFILE. En ese caso se debe usar en su lugar algún otro programa en el cliente como mysql -e "SELECT ..." > outfile en el ordenador cliente para generar el fichero. SELECT ... INTO OUTFILE es el complemento de LOAD DATA INFILE; la sintaxis para la parte export_options de la sentencia es la misma que para las cláusulas FIELDS y LINES que se usan con la sentencia LOAD DATA INFILE. FIELDS SCAPED BY controla el modo en que se escriben los caracteres especiales. Si el carácter de FIELDS ESCAPED BY no es vacío, se usará como prefijo para los siguientes caracteres en la salida:
    • El carácter ESCAPED BY.
    • El carácter FIELDS [OPTIONALLY] ENCLOSED BY.
    • El primer carácter de los valores FIELDS TERMINATED BY y LINES TERMINATED BY.
    • ASCII 0 (que actualmente se escribe seguido del carácter de escape ASCII `0', no un byte de valor cero.
    Si el caácter FIELDS ESCAPED BY se deja vacío, no se escapa ningún carácter y NULL se muestra como NULL, no \N. Probablemente no sea una buena idea especificar un carácter de escape vacío, sobre todo si existen valores de columnas en los datos que contengan cualquiera de los caracteres de la lista dada. El motivo de esto es que que se debe escapar cualquier carácter FIELDS TERMINATED BY, ESCAPED BY o LINES TERMINATED BY para que sea posible leer el fichero más tarde. El carácter ASCII NUL se escapa para que sea más fácil visualizarlo. Como el fichero resultante no tiene que seguir la sintaxis SQL, no es necesario escapar nada más. He aquí un ejemplo para obtener un fichero en formato de valores separados con comas usado por muchos programas:
    SELECT a,b,a+b INTO OUTFILE "/tmp/result.text"
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY "\n"
    FROM test_table;
  • Si se usa INTO DUMPFILE en lugar de INTO OUTFILE, MySQL sólo escribirá una fila en el fichero, sin tabulaciones o terminadores y sin realizar ningún proceso de escapado. Esto es práctico si se quiere almacenar un valor BLOB en un fichero.
  • Nota: Cualquier fichero creado por INTO OUTFILE y INTO DUMPFILE debe tener permiso de escritura para todos los usuarios en el servidor. El motivo es que el servidor MySQL no puede crear un fichero cuyo dueño sea alguien diferente que el usuario que hace la consulta (nunca se debe ejecutar MySQL como root). De modo que el fichero debe tener permiso de escritura para todo el mundo para que se pueda manejar su contenido.
  • Una cláusula PROCEDURE nombra a un procedimiento que debe procesar los datos en el conjunto de resultados.
  • Si se usa FOR UPDATE en un proceso de almacenamiento con bloqueo de página o de filas, las filas examinadas estarán bloquedas para escritura hasta el final de la operación actual. Usando IN SHARE MODE activa el bloqueo de compartir que evita que otras transacciones puedan actualizar o borrar las filas examinadas.

A continuación de la palabra clave SELECT, se pueden añadir determinadas opciones que afectan al funcionamiento de la sentencia.

Las opciones ALL, DISTINCT y DISTINCTROW especifican si las filas duplicadas deben ser devueltas. Si no se da ninguna de estas opciones, por defecto se usa ALL (se devuelven todas las filas coincidentes). DISTINCT y DISTINCTROW son sinónimos y especifican que las filas duplicadas en el conjunto de resultados deben ser eliminadas.

HIGH_PRIORITY, STRAIGHT_JOIN y las opciones que empiezan con SQL_ son extensiones MySQL al SQL estándar.

  • HIGH_PRIORITY dará a SELECT mayor prioridad que a sentencias que actualicen una tabla. Sólo se debe usar para consultas que sean muy rápidas y deban ser hechas inmediatamente. Una consulta SELECT HIGH_PRIORITY que se realice mientras la tabla esté bloqueada para lectura se realizará aunque exista una sentencia de actualización que esté esperando a que la table deje de estar bloqueada. HIGH_PRIORITY no se puede usar con sentecias SELECT que sean parte de una UNION.
  • STRAIGHT_JOIN fuerza el optimizador a unir tablas en el orden en que han sido listadas en la cláusula FROM. Se puede usar para mejorar la velocidad de una consulta si el optimizador une las tablas en un orden no óptimo. Consultar EXPLAIN. STRAIGHT_JOIN también puede ser usado en la lista de table_references. Ver JOIN

  • SQL_BIG_RESULT puede ser usada con GROUP BY o DISTINCT para informar al optimizador que el conjunto resultados puede contener muchas filas. En ese caso, MySQL podrá usar directametne tablas temporales en disco si es necesario. MySQL puede también, en este caso, optar por ordenar una tabla temporal con una clave dentro de los elementos GROUP BY.
  • SQL_BUFFER_RESULT fuerza que el resultado sea colocado en una tabla temporal. Esto ayuda a MySQL a librerar bloqueos en tablas más rápidamente y ayuda en casos donde toma mucho tiempo en enviar los datos al cliente.
  • SQL_SMALL_RESULT, puede usarse con GROUP BY o DISTINCT para informar al optimizador que el resultado será pequeño. En ese caso, MySQL usa tablas temporales rápidas para almecenar la tabla resultado en lugar de usar ordenamiento. A partir de MySQL 3.23 esto normalmente no es necesario.
  • SQL_CALC_FOUND_ROWS (versión 4.0.0 y siguientes) indica a MySQL que calcule cuántas filas contendrá el conjunto de resultados, ignorando cualquier cláusula LIMIT. El número de filas puede recuperarse con SELECT FOUND_ROWS(). Con versiones anteriores a la 4.1.0 esto no funcionará junto con LIMIT 0, ya que está optimizado de modo que regrese instantaneamente (resultando un número de filas igual a cero).
  • SQL_CACHE dice a MySQL que almacene el resultado de la consulta en un caché si se usa un valor 2 o DEMAND para QUERY_CACHE_TYPE. Para una consulta que use UNION o subconsultas, esta opción tendrá efecto al ser usada en cualquier SELECT de la consulta.
  • SQL_NO_CACHE indica a MySQL que no almacene el resultado de la consulta en el caché de consulta. Para una consulta que use UNION o subconsultas, esta opción tendrá efecto al ser usada en cualquier SELECT de la consulta.