SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY] [DISTINCT | DISTINCTROW | ALL] select_expression,... [INTO {OUTFILE | DUMPFILE} 'file_name' export_options] [FROM table_references [WHERE where_definition] [GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_definition] [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...] [LIMIT [offset,] row_count | row_count OFFSET offset] [PROCEDURE procedure_name(argument_list)] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT is used to retrieve rows selected from one or more tables. Each select_expression indicates a column you want to retrieve. SELECT may also be used to retrieve rows computed without reference to any table.
For example:
mysql> SELECT 1 + 1; -> 2
All clauses used must be given in exactly the order shown in the syntax description. For example, a HAVING clause must come after any GROUP BY clause and before any ORDER BY clause.
A SELECT expression may be given an alias using AS alias_name. The alias is used as the expression's column name and can be used with ORDER BY or HAVING clauses. For example:
mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
The AS keyword is optional when aliasing a SELECT expression. The preceding example could have been written like this:
mysql> SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;
Because the AS is optional, a subtle problem can occur if you forget the comma between two SELECT expressions: MySQL will interpret the second as an alias name. For example, in the following statement, columnb is treated as an alias name:
mysql> SELECT columna columnb FROM mytable;
It is not allowed to use a column alias in a WHERE clause, because the column value may not yet be determined when the WHERE clause is executed. See Problems with alias.
The FROM table_references clause indicates the tables from which to retrieve rows. If you name more than one table, you are performing a join. For information on join syntax, see JOIN. For each table specified, you may optionally specify an alias.
table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]
As of MySQL Version 3.23.12, you can give hints about which index MySQL should use when retrieving information from a table. This is useful if EXPLAIN shows that MySQL is using the wrong index from the list of possible indexes. By specifying USE INDEX (key_list), you can tell MySQL to use only one of the possible indexes to find rows in the table. The alternative syntax IGNORE INDEX (key_list) can be used to tell MySQL to not use some particular index.
In MySQL 4.0.9 you can also use FORCE INDEX. This acts likes USE INDEX (key_list) but with the addition that a table scan is assumed to be VERY expensive. In other words a table scan will only be used if there is no way to use one of the given index to find rows in the table.
USE/IGNORE/FORCE KEY are synonyms for USE/IGNORE/FORCE INDEX.
Note: USE/IGNORE/FORCE INDEX only affects which indexes are used when MySQL decides how to find rows in the table and how to do the join. It doesn't affect whether an index will be used when resolving an ORDER BY or GROUP BY.
In MySQL 4.0.14, you can use SET MAX_SEEKS_FOR_KEY=value as an alternative way to force MySQL to prefer key scans instead of table scans.
You can refer to a table as tbl_name (within the current database), or as dbname.tbl_name to explicitly specify a database. You can refer to a column as col_name, tbl_name.col_name, or db_name.tbl_name.col_name. You need not specify a tbl_name or db_name.tbl_name prefix for a column reference in a SELECT statement unless the reference would be ambiguous. See Legal names, for examples of ambiguity that require the more explicit column reference forms.
From version 4.1.0, you are allowed to specify DUAL as a dummy table name, in situations where no tables are referenced. This is purely compatibility feature, some other servers require this syntax.
mysql> SELECT 1 + 1 FROM DUAL; -> 2
A table reference may be aliased using 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;
Columns selected for output may be referred to in ORDER BY and GROUP BY clauses using column names, column aliases, or column positions. Column positions begin with 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;
To sort in reverse order, add the DESC (descending) keyword to the name of the column in the ORDER BY clause that you are sorting by. The default is ascending order; this may be specified explicitly using the ASC keyword.
In the WHERE clause, you can use any of the functions that MySQL supports, except for aggregate (summary) functions. See Functions.
The HAVING clause can refer to any column or alias named in the select_expression. It is applied nearly last, just before items are sent to the client, with no optimization. (LIMIT is applied after HAVING.) Don't use HAVING for items that should be in the WHERE clause. For example, do not write this:
mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;
Write this instead:
mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;
In MySQL Version 3.22.5 or later, you can also write queries like this:
mysql> SELECT user,MAX(salary) FROM users -> GROUP BY user HAVING MAX(salary)>10;
In older MySQL versions, you can write this instead:
mysql> SELECT user,MAX(salary) AS sum FROM users -> group by user HAVING sum>10;
The options DISTINCT, DISTINCTROW and ALL specify whether duplicate rows should be returned. The default is (ALL), all matching rows are returned. DISTINCT and DISTINCTROW are synonyms and specify that duplicate rows in the result set should be removed.
STRAIGHT_JOIN, HIGH_PRIORITY, and options beginning with SQL_ are MySQL extensions to SQL-99.
STRAIGHT_JOIN forces the optimizer to join the tables in the order in which they are listed in the FROM clause. You can use this to speed up a query if the optimizer joins the tables in non-optimal order. See EXPLAIN.
HIGH_PRIORITY will give the SELECT higher priority than a statement that updates a table. You should only use this for queries that are very fast and must be done at once. A SELECT HIGH_PRIORITY query will run if the table is locked for read even if there is an update statement that is waiting for the table to be free.
SQL_BIG_RESULT can be used with GROUP BY or DISTINCT to tell the optimizer that the result set will have many rows. In this case, MySQL will directly use disk-based temporary tables if needed. MySQL will also, in this case, prefer sorting to doing a temporary table with a key on the GROUP BY elements.
SQL_BUFFER_RESULT forces the result to be put into a temporary table. This helps MySQL free the table locks early and helps in cases where it takes a long time to send the result set to the client.
SQL_SMALL_RESULT, a MySQL-specific option, can be used with GROUP BY or DISTINCT to tell the optimizer that the result set will be small. In this case, MySQL uses fast temporary tables to store the resulting table instead of using sorting. In MySQL Version 3.23 this shouldn't normally be needed.
SQL_CALC_FOUND_ROWS (version 4.0.0 and up) tells MySQL to calculate how many rows there would be in the result set, disregarding any LIMIT clause. The number of rows can then be retrieved with SELECT FOUND_ROWS(). See Miscellaneous functions.
Please note that in versions prior to 4.1.0 this does not work with LIMIT 0, which is optimized to return instantly (resulting in a row count of 0). See LIMIT optimisation.
SQL_CACHE tells MySQL to store the query result in the query cache if you are using QUERY_CACHE_TYPE=2 (DEMAND). See Query Cache. For a query that uses UNION or subqueries, this option takes effect to be used in any SELECT of the query.
SQL_NO_CACHE tells MySQL not to store the query result in the query cache. See Query Cache. For a query that uses UNION or subqueries, this option takes effect to be used in any SELECT of the query.
If you use GROUP BY, the output rows will be sorted according to the GROUP BY as if you had an ORDER BY over all the fields in the GROUP BY. MySQL has extended the GROUP BY clause so that you can also specify ASC and DESC after columns named in the clause:
SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
MySQL has extended the use of GROUP BY to allow you to select fields that are not mentioned in the GROUP BY clause. If you are not getting the results you expect from your query, please read the GROUP BY description. See Group by functions and modifiers.
As of MySQL 4.1.1, GROUP BY allows a WITH ROLLUP modifier. See GROUP BY Modifiers.
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must be integer constants.
With one argument, the value specifies the number of rows to return from the beginning of the result set. With two arguments, the first specifies the offset of the first row to return, the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
To be compatible with PostgreSQL MySQL also supports the syntax: LIMIT row_count OFFSET offset.
mysql> SELECT * FROM table LIMIT 5,10; # Retrieve rows 6-15
To retrieve all rows from a certain offset up to the end of the result set, you can use some big number for the second parameter:
mysql> SELECT * FROM table LIMIT 95,18446744073709551615; # Retrieve rows 96-last.
If one argument is given, it indicates the maximum number of rows to return:
mysql> SELECT * FROM table LIMIT 5; # Retrieve first 5 rows
In other words, LIMIT n is equivalent to LIMIT 0,n.
The SELECT ... INTO OUTFILE 'file_name' form of SELECT writes the selected rows to a file. The file is created on the server host and cannot already exist (among other things, this prevents database tables and files such as /etc/passwd from being destroyed). You must have the FILE privilege on the server host to use this form of SELECT.
The SELECT ... INTO OUTFILE statement is intended primarily to let you very quickly dump a table on the server machine. If you want to create the resulting file on some other host than the server host, you can't use SELECT ... INTO OUTFILE. In this case you should instead use some client program like mysqldump --tab or mysql -e "SELECT ..." > outfile to generate the file.
SELECT ... INTO OUTFILE is the complement of LOAD DATA INFILE; the syntax for the export_options part of the statement consists of the same FIELDS and LINES clauses that are used with the LOAD DATA INFILE statement. See LOAD DATA.
In the resulting text file, only the following characters are escaped by the ESCAPED BY character:
The ESCAPED BY character
The first character in FIELDS TERMINATED BY
The first character in LINES TERMINATED BY
Additionally, ASCII 0 is converted to ESCAPED BY followed by 0 (ASCII 48).
The reason for the above is that you must escape any FIELDS TERMINATED BY, ESCAPED BY, or LINES TERMINATED BY characters to reliably be able to read the file back. ASCII 0 is escaped to make it easier to view with some pagers.
As the resulting file doesn't have to conform to the SQL syntax, nothing else need be escaped.
Here follows an example of getting a file in the format used by many old programs.
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM test_table;
If you use INTO DUMPFILE instead of INTO OUTFILE, MySQL will only write one row into the file, without any column or line terminations and without performing any escape processing. This is useful if you want to store a BLOB value in a file.
Note that any file created by INTO OUTFILE and INTO DUMPFILE will be writeable by all users on the server host! The reason is that the MySQL server can't create a file that is owned by anyone else than the user it's running as (you should never run mysqld as root). The file thus must be world-writeable so that you can manipulate its contents.
A PROCEDURE clause names a procedure that should process the data in the result set. For an example, see procedure analyse.
If you use FOR UPDATE on a storage engine with page or row locks, the examined rows are write locked until the end of the current transaction.
MySQL supports the following JOIN syntaxes for use in SELECT statements:
table_reference, table_reference table_reference [INNER | CROSS] JOIN table_reference [join_condition] table_reference STRAIGHT_JOIN table_reference table_reference LEFT [OUTER] JOIN table_reference [join_condition] table_reference NATURAL [LEFT [OUTER]] JOIN table_reference { OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr } table_reference RIGHT [OUTER] JOIN table_reference [join_condition] table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
Where table_reference is defined as:
table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]
and join_condition is defined as:
ON conditional_expr | USING (column_list)
You should generally not have any conditions in the ON part that are used to restrict which rows you want in the result set, but rather specify these conditions in the WHERE clause. There are exceptions to this rule.
Note that INNER JOIN syntax allows a join_condition only from MySQL 3.23.17 on. The same is true for JOIN and CROSS JOIN only as of MySQL 4.0.11.
The last LEFT OUTER JOIN syntax shown in the preceding list exists only for compatibility with ODBC:
A table reference may be aliased using tbl_name AS alias_name or tbl_name alias_name:
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 -> WHERE t1.name = t2.name;
The ON conditional is any conditional of the form that may be used in a WHERE clause.
If there is no matching record for the right table in the ON or USING part in a LEFT JOIN, a row with all columns set to NULL is used for the right table. You can use this fact to find records in a table that have no counterpart in another table:
mysql> SELECT table1.* FROM table1 -> LEFT JOIN table2 ON table1.id=table2.id -> WHERE table2.id IS NULL;
This example finds all rows in table1 with an id value that is not present in table2 (that is, all rows in table1 with no corresponding row in table2). This assumes that table2.id is declared NOT NULL. See LEFT JOIN optimisation.
The USING (column_list) clause names a list of columns that must exist in both tables. The following two clauses are semantically identical:
a LEFT JOIN b USING (c1,c2,c3) a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
The NATURAL [LEFT] JOIN of two tables is defined to be semantically equivalent to an INNER JOIN or a LEFT JOIN with a USING clause that names all columns that exist in both tables.
INNER JOIN and , (comma) are semantically equivalent in the absence of a join condition: both will produce a Cartesian product between the specified tables (that is, each and every row in the first table will be joined onto all rows in the second table).
RIGHT JOIN works analogously to LEFT JOIN. To keep code portable across databases, it's recommended to use LEFT JOIN instead of RIGHT JOIN.
STRAIGHT_JOIN is identical to JOIN, except that the left table is always read before the right table. This can be used for those (few) cases where the join optimizer puts the tables in the wrong order.
As of MySQL Version 3.23.12, you can give hints about which index MySQL should use when retrieving information from a table. This is useful if EXPLAIN shows that MySQL is using the wrong index from the list of possible indexes. By specifying USE INDEX (key_list), you can tell MySQL to use only one of the possible indexes to find rows in the table. The alternative syntax IGNORE INDEX (key_list) can be used to tell MySQL to not use some particular index.
In MySQL 4.0.9 you can also use FORCE INDEX. This acts likes USE INDEX (key_list) but with the addition that a table scan is assumed to be VERY expensive. In other words a table scan will only be used if there is no way to use one of the given index to find rows in the table.
USE/IGNORE KEY are synonyms for USE/IGNORE INDEX.
Note: USE/IGNORE/FORCE INDEX only affects which indexes are used when MySQL decides how to find rows in the table and how to do the join. It doesn't affect whether an index will be used when resolving an ORDER BY or GROUP BY.
Some examples:
mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id); mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id -> LEFT JOIN table3 ON table2.id=table3.id; mysql> SELECT * FROM table1 USE INDEX (key1,key2) -> WHERE key1=1 AND key2=2 AND key3=3; mysql> SELECT * FROM table1 IGNORE INDEX (key3) -> WHERE key1=1 AND key2=2 AND key3=3;
SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
UNION is implemented in MySQL 4.0.0.
UNION is used to combine the result from many SELECT statements into one result set.
The columns listed in the select_expression portion of the SELECT should have the same type. The column names used in the first SELECT query will be used as the column names for the results returned.
The SELECT commands are normal select commands, but with the following restrictions:
Only the last SELECT command can have INTO OUTFILE.
If you don't use the keyword ALL for the UNION, all returned rows will be unique, as if you had done a DISTINCT for the total result set. If you specify ALL, then you will get all matching rows from all the used SELECT statements.
The DISTINCT keyword is an optional word (introduced in MySQL 4.0.17) that does nothing. But it is required by the SQL standard.
If you want to use an ORDER BY for the total UNION result, you should use parentheses:
(SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM table_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10) ORDER BY a;
Note: You cannot mix UNION ALL and UNION DISTINCT in the same query yet. If you use ALL for one UNION then it is used for all of them.
The types and lengths of the columns in the result set of a UNION take into acccount the values retrieved by all the SELECT statements. Before MySQL 4.1.1, a limitation of UNION is that only the values from the first SELECT were used to determine result types and lengths. This could result in value truncation if, for example, the second SELECT retrieved longer values than the first SELECT:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10); +---------------+ | REPEAT('a',1) | +---------------+ | a | | b | +---------------+
That limitation has been removed as of MySQL 4.1.1:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10); +---------------+ | REPEAT('a',1) | +---------------+ | a | | bbbbbbbbbb | +---------------+