8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

15.2.13 SELECT 语句15.2.13 SELECT Statement

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
    [HIGH_PRIORITY]
    [STRAIGHT_JOIN]
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
    [SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr] ...
    [into_option]
    [FROM table_references
      [PARTITION partition_list]]
    [WHERE where_condition]
    [GROUP BY [ {col_name | expr | position}, ... [WITH ROLLUP]
              | ROLLUP ({col_name | expr | position}, ...)] ]
    [HAVING where_condition]
    [WINDOW window_name AS (window_spec)
        [, window_name AS (window_spec)] ...]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [into_option]
    [FOR {UPDATE | SHARE}
        [OF tbl_name [, tbl_name] ...]
        [NOWAIT | SKIP LOCKED]
      | LOCK IN SHARE MODE]
    [into_option]

into_option: {
    INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
  | INTO DUMPFILE 'file_name'
  | INTO var_name [, var_name] ...
}

export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]

SELECT 用于检索从一个或多个表中选取的行,可以包含 UNION 操作和子查询。INTERSECT 和 EXCEPT 操作也支持。UNIONINTERSECT,以及 EXCEPT 运算符,在本节后面将有更详细的描述。另见 第 15.2.15 节,“子查询”。SELECT is used to retrieve rows selected from one or more tables, and can include UNION operations and subqueries. INTERSECT and EXCEPT operations are also supported. The UNION, INTERSECT, and EXCEPT operators are described in more detail later in this section. See also Section 15.2.15, “Subqueries”.

SELECT 语句可以以 WITH 子句来定义在 SELECT。参见 第 15.2.20 节,“WITH (Common Table Expressions)”。A SELECT statement can start with a WITH clause to define common table expressions accessible within the SELECT. See Section 15.2.20, “WITH (Common Table Expressions)”.

最常见的子句 SELECT 语句如下:The most commonly used clauses of SELECT statements are these:

  • 每个select_expr表示您想要检索的列。必须至少有一列select_expr.Each select_expr indicates a column that you want to retrieve. There must be at least one select_expr.

  • table_references指示要从中检索行的表或表。其语法在第 15.2.13.2 节,“JOIN 子句”.table_references indicates the table or tables from which to retrieve rows. Its syntax is described in Section 15.2.13.2, “JOIN Clause”.

  • SELECT支持使用子句通过列出分区或子分区(或两者)来显式选择分区PARTITION位于表名之后的table_reference(见第 15.2.13.2 节,“JOIN 子句”。在这种情况下,仅从列出的分区中选择行,表的任何其他分区将被忽略。有关更多信息和示例,请参见第 26.5 节,“分区选择”.SELECT supports explicit partition selection using the PARTITION clause with a list of partitions or subpartitions (or both) following the name of the table in a table_reference (see Section 15.2.13.2, “JOIN Clause”). In this case, rows are selected only from the partitions listed, and any other partitions of the table are ignored. For more information and examples, see Section 26.5, “Partition Selection”.

  • 该WHERE clause, if given, indicates the condition or conditions that rows must satisfy to be selected. where_condition is an expression that evaluates to true for each row to be selected. The statement selects all rows if there is no WHERE子句创建的表空间。The WHERE clause, if given, indicates the condition or conditions that rows must satisfy to be selected. where_condition is an expression that evaluates to true for each row to be selected. The statement selects all rows if there is no WHERE clause.

    在 WHERE 表达式中,你可以使用 MySQL 支持的任何函数和运算符,但聚合(群)函数除外。参见 第 11.5 节“表达式”,以及 第 14 章,函数与运算符。In the WHERE expression, you can use any of the functions and operators that MySQL supports, except for aggregate (group) functions. See Section 11.5, “Expressions”, and Chapter 14, Functions and Operators.

SELECT 也可以用于检索未引用任何表计算的行。SELECT can also be used to retrieve rows computed without reference to any table.

例如:For example:

mysql> SELECT 1 + 1;
        -> 2

在未引用任何表的情况下,您可以指定 DUAL 作为虚拟表名: You are permitted to specify DUAL as a dummy table name in situations where no tables are referenced:

mysql> SELECT 1 + 1 FROM DUAL;
        -> 2

DUAL 完全是为了方便那些要求所有 SELECT 语句必须包含 FROM 以及可能的其他子句的人。MySQL 可能会忽略这些子句。如果没有引用任何表,MySQL 并不要求 FROM DUAL。DUAL is purely for the convenience of people who require that all SELECT statements should have FROM and possibly other clauses. MySQL may ignore the clauses. MySQL does not require FROM DUAL if no tables are referenced.

通常,使用的子句必须按语法描述中显示的顺序给出。例如,HAVING 子句必须在任何 GROUP BY 子句之后并在任何 ORDER BY 子句之前。INTO 子句(如果存在)可以出现在语法描述指示的任何位置,但在同一条语句中只能出现一次,不能出现在多个位置。有关 INTO 的更多信息,请参见 第 15.2.13.1 节,“SELECT ... INTO 语句”。In general, 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. The INTO clause, if present, can appear in any position indicated by the syntax description, but within a given statement can appear only once, not in multiple positions. For more information about INTO, see Section 15.2.13.1, “SELECT ... INTO Statement”.

select_expr 列表包含了指示要检索哪些列的选择列表。各项可以指定列或表达式,也可以使用 * 简写:The list of select_expr terms comprises the select list that indicates which columns to retrieve. Terms specify a column or expression or can use *-shorthand:

  • 一个仅包含单个未限定的 * 的选择列表可用于简写,以选择所有表的所有列:A select list consisting only of a single unqualified * can be used as shorthand to select all columns from all tables:

    SELECT * FROM t1 INNER JOIN t2 ...
    
  • tbl_name.* 可作为限定的简写,用于选择指定表的所有列:tbl_name.* can be used as a qualified shorthand to select all columns from the named table:

    SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...
    
  • 如果表中有不可见列,* 和 tbl_name.* 不包括它们。要包括不可见列,必须显式引用它们。If a table has invisible columns, * and tbl_name.* do not include them. To be included, invisible columns must be referenced explicitly.

  • 在选择列表中将未限定的 * 与其他项一起使用可能会导致解析错误。例如:Use of an unqualified * with other items in the select list may produce a parse error. For example:

    SELECT id, * FROM t1
    

    为避免此问题,请使用限定的 tbl_name.* 引用:To avoid this problem, use a qualified tbl_name.* reference:

    SELECT id, t1.* FROM t1
    

    对于选择列表中的每个表,请使用限定的 tbl_name.* 引用:Use qualified tbl_name.* references for each table in the select list:

    SELECT AVG(score), t1.* FROM t1 ...
    

下面的列表提供了关于其他 SELECT 子句的附加信息:The following list provides additional information about other SELECT clauses:

  • 可以使用 select_expr 为 AS alias_name 指定别名。别名用于表达式的列名,并可用于 GROUP BY、ORDER BY 或 HAVING 子句。例如: A select_expr can be given an alias using AS alias_name. The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses. For example:

    SELECT CONCAT(last_name,', ',first_name) AS full_name
      FROM mytable ORDER BY full_name;
    

    当为 select_expr 使用标识符创建别名时,AS 关键字是可选的。前面的例子也可以这样写:The AS keyword is optional when aliasing a select_expr with an identifier. The preceding example could have been written like this:

    SELECT CONCAT(last_name,', ',first_name) full_name
      FROM mytable ORDER BY full_name;
    

    然而,由于 AS 是可选的,如果在两个 select_expr 表达式之间忘记了逗号,可能会发生微妙的问题:MySQL 会将第二个解释为别名。例如,在以下语句中,columnb 被视为一个别名:However, because the AS is optional, a subtle problem can occur if you forget the comma between two select_expr expressions: MySQL interprets the second as an alias name. For example, in the following statement, columnb is treated as an alias name:

    SELECT columna columnb FROM mytable;
    

    因此,在指定列别名时,习惯明确使用 AS。For this reason, it is good practice to be in the habit of using AS explicitly when specifying column aliases.

    在 WHERE,因为执行 WHERE。参见 B.3.4.4 节,“列别名问题”。It is not permissible to refer to a column alias in a WHERE clause, because the column value might not yet be determined when the WHERE clause is executed. See Section B.3.4.4, “Problems with Column Aliases”.

  • FROM table_references 子句表示要检索行的表。如果你命名多个表,就是在执行连接。有关连接语法的信息,请参见 第 15.2.13.2 节,“JOIN Clause”。对于每个指定的表,你可以选择一个别名。 The FROM table_references clause indicates the table or tables from which to retrieve rows. If you name more than one table, you are performing a join. For information on join syntax, see Section 15.2.13.2, “JOIN Clause”. For each table specified, you can optionally specify an alias.

    tbl_name [[AS] alias] [index_hint]
    

    使用索引提示为优化器提供了查询处理过程中如何选择索引的信息。关于指定这些提示的语法描述,请参见 第 10.9.4 节,“索引提示”。The use of index hints provides the optimizer with information about how to choose indexes during query processing. For a description of the syntax for specifying these hints, see Section 10.9.4, “Index Hints”.

    您可以使用SET max_seeks_for_key=value作为另一种方法来强制 MySQL 优先使用键扫描而不是表扫描。请参见第 7.1.8 节,“服务器系统变量”.You can use SET max_seeks_for_key=value as an alternative way to force MySQL to prefer key scans instead of table scans. See Section 7.1.8, “Server System Variables”.

  • You can refer to a table within the default database as tbl_name, or as db_name.tbl_name to specify a database explicitly. You can refer to a column as col_name, tbl_name.col_name,或db_name.tbl_name.col_name. You need not specify a tbl_name或者db_name.tbl_name prefix for a column reference unless the reference would be ambiguous. See Section 11.2.2, “Identifier Qualifiers”, for examples of ambiguity that require the more explicit column reference forms.You can refer to a table within the default database as tbl_name, or as db_name.tbl_name to specify a database explicitly. 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 unless the reference would be ambiguous. See Section 11.2.2, “Identifier Qualifiers”, for examples of ambiguity that require the more explicit column reference forms.

  • A table reference can be aliased using tbl_name AS alias_name或者tbl_name alias_name. These statements are equivalent: A table reference can be aliased using tbl_name AS alias_name or tbl_name alias_name. These statements are equivalent:

    SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
      WHERE t1.name = t2.name;
    
    SELECT t1.name, t2.salary FROM employee t1, info t2
      WHERE t1.name = t2.name;
    
  • 选择输出的列可以用 ORDER BY 和 GROUP BY 子句,使用列名、列别名或列位置来引用。列位置为整数,开头为 1: Columns selected for output can be referred to in ORDER BY and GROUP BY clauses using column names, column aliases, or column positions. Column positions are integers and begin with 1:

    SELECT college, region, seed FROM tournament
      ORDER BY region, seed;
    
    SELECT college, region AS r, seed AS s FROM tournament
      ORDER BY r, s;
    
    SELECT college, region, seed FROM tournament
      ORDER BY 2, 3;
    

    要逆序排序,在DESC。默认为升序;这可以通过ASC。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 can be specified explicitly using the ASC keyword.

    如果ORDER BY出现在括号中的查询表达式中,并且也应用在外部查询中,结果为未定义,未来 MySQL 版本可能会有所变化。If ORDER BY occurs within a parenthesized query expression and also is applied in the outer query, the results are undefined and may change in a future version of MySQL.

    该语法已从 SQL 标准中移除,列位置的使用已被弃用。Use of column positions is deprecated because the syntax has been removed from the SQL standard.

  • 当你使用 ORDER BY 或 GROUP BY 来排序 SELECT时,服务器只用系统变量 max_sort_length。 When you use ORDER BY or GROUP BY to sort a column in a SELECT, the server sorts values using only the initial number of bytes indicated by the max_sort_length system variable.

  • MySQL 扩展了GROUP BY的使用,以允许选择未在GROUP BY子句中提及的字段。如果您没有从查询获得预期的结果,请阅读GROUP BY中描述的第 14.19 节,“聚合函数”.MySQL extends the use of GROUP BY to permit selecting fields that are not mentioned in the GROUP BY clause. If you are not getting the results that you expect from your query, please read the description of GROUP BY found in Section 14.19, “Aggregate Functions”.

  • HAVING 子句,类似于 WHERE 子句,指定了选择条件。WHERE 子句指定了选择列表中列的条件,但不能引用聚合函数。HAVING 子句指定了组的条件,通常由 GROUP BY 子句构成。查询结果仅包含满足 HAVING 条件的组。(如果不存在 GROUP BY,则所有行隐式构成一个聚合组。)The HAVING clause, like the WHERE clause, specifies selection conditions. The WHERE clause specifies conditions on columns in the select list, but cannot refer to aggregate functions. The HAVING clause specifies conditions on groups, typically formed by the GROUP BY clause. The query result includes only groups satisfying the HAVING conditions. (If no GROUP BY is present, all rows implicitly form a single aggregate group.)

    HAVING 子句几乎是最后应用的,就在发送给客户端的项目之前,且没有优化。(LIMIT 是在 HAVING的。)The HAVING clause is applied nearly last, just before items are sent to the client, with no optimization. (LIMIT is applied after HAVING.)

    SQL 标准要求 HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列。然而,MySQL 支持对此行为的扩展,并允许 HAVING 引用 SELECT 列表及外部子查询中的列。The SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions. However, MySQL supports an extension to this behavior, and permits HAVING to refer to columns in the SELECT list and columns in outer subqueries as well.

    如果 HAVING 子句指的是歧义列,则会触发警告。在以下语句中,col2 存在歧义,因为它既用作别名,也用作列名:If the HAVING clause refers to a column that is ambiguous, a warning occurs. In the following statement, col2 is ambiguous because it is used as both an alias and a column name:

    SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
    

    优先考虑标准 SQL 行为,因此如果 HAVING 列名同时用于 GROUP BY 以及作为 select 列列表中的别名列,那么优先考虑 GROUP BY 列中的列。Preference is given to standard SQL behavior, so if a HAVING column name is used both in GROUP BY and as an aliased column in the select column list, preference is given to the column in the GROUP BY column.

  • 不要使用 HAVING 用于应属于 WHERE 子句中的项。例如,不要写以下内容:Do not use HAVING for items that should be in the WHERE clause. For example, do not write the following:

    SELECT col_name FROM tbl_name HAVING col_name > 0;
    

    请写这个:Write this instead:

    SELECT col_name FROM tbl_name WHERE col_name > 0;
    
  • HAVING 子句可以指聚合函数,而 WHERE 子句则不能:The HAVING clause can refer to aggregate functions, which the WHERE clause cannot:

    SELECT user, MAX(salary) FROM users
      GROUP BY user HAVING MAX(salary) > 10;
    

    (在某些旧版本的 MySQL 中此功能不成立。)(This did not work in some older versions of MySQL.)

  • MySQL permits duplicate column names. That is, there can be more than one select_expr with the same name. This is an extension to standard SQL. Because MySQL also permits GROUP BY以及HAVING to refer to select_expr values, this can result in an ambiguity:MySQL permits duplicate column names. That is, there can be more than one select_expr with the same name. This is an extension to standard SQL. Because MySQL also permits GROUP BY and HAVING to refer to select_expr values, this can result in an ambiguity:

    SELECT 12 AS a, a FROM t GROUP BY a;
    

    在该语句中,两个列都具有名称a。为了确保用于分组的列正确,请为每个列使用不同的名称select_expr.In that statement, both columns have the name a. To ensure that the correct column is used for grouping, use different names for each select_expr.

  • WINDOW 子句(如存在)定义了可被窗口函数引用的命名窗口。详情请参见 第 14.20.4 节,“Named Windows”。The WINDOW clause, if present, defines named windows that can be referred to by window functions. For details, see Section 14.20.4, “Named Windows”.

  • MySQL resolves unqualified column or alias references in ORDER BY clauses by searching in the select_expr values, then in the columns of the tables in the FROM clause. For GROUP BY或者HAVING clauses, it searches the FROM clause before searching in the select_expr values. (For GROUP BY以及HAVING, this differs from the pre-MySQL 5.0 behavior that used the same rules as for ORDER BY.)MySQL resolves unqualified column or alias references in ORDER BY clauses by searching in the select_expr values, then in the columns of the tables in the FROM clause. For GROUP BY or HAVING clauses, it searches the FROM clause before searching in the select_expr values. (For GROUP BY and HAVING, this differs from the pre-MySQL 5.0 behavior that used the same rules as for ORDER BY.)

  • LIMIT 子句可用于限制 SELECT 语句。LIMIT 取一或两个数值参数,且两者必须都是非负整数常量,但有以下例外: 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 both be nonnegative integer constants, with these exceptions:

    • 在预备语句中,LIMIT 参数可用 ?。用占位符来指定。Within prepared statements, LIMIT parameters can be specified using ? placeholder markers.

    • 在存储程序中,LIMIT 参数可用整数值例程参数或局部变量指定。Within stored programs, LIMIT parameters can be specified using integer-valued routine parameters or local variables.

    有两个参数时,第一个参数指定返回第一行的偏移量,第二个参数指定返回的最大行数。初始行的偏移量为 0(而非 1):With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):

    SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15
    

    要检索某一偏移量到结果集末尾的所有行,可以使用较大的数字作为第二个参数。该语句检索从第 96 行到最后一行的所有行:To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:

    SELECT * FROM tbl LIMIT 95,18446744073709551615;
    

    其中一个参数,值指定从结果集起点返回的行数:With one argument, the value specifies the number of rows to return from the beginning of the result set:

    SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows
    

    换句话说,LIMIT row_count等同于LIMIT 0, row_count.In other words, LIMIT row_count is equivalent to LIMIT 0, row_count.

    对于预备语句,可以使用占位符。以下语句返回 tbl:For prepared statements, you can use placeholders. The following statements return one row from the tbl table:

    SET @a=1;
    PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?';
    EXECUTE STMT USING @a;
    

    以下语句返回 tbl:The following statements return the second to sixth rows from the tbl table:

    SET @skip=1; SET @numrows=5;
    PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?';
    EXECUTE STMT USING @skip, @numrows;
    

    为兼容 PostgreSQL,MySQL 还支持 LIMIT row_count OFFSET offset 语法。For compatibility with PostgreSQL, MySQL also supports the LIMIT row_count OFFSET offset syntax.

    如果 LIMIT 出现在括号中的查询表达式中,并且应用在外部查询中,结果未定义,未来版本的 MySQL 可能会有所变化。If LIMIT occurs within a parenthesized query expression and also is applied in the outer query, the results are undefined and may change in a future version of MySQL.

  • SELECT ... INTO 形式为 SELECT 允许查询结果写入文件或存储在变量中。更多信息请参见 第 15.2.13.1 节,“SELECT ...INTO 语句”。The SELECT ... INTO form of SELECT enables the query result to be written to a file or stored in variables. For more information, see Section 15.2.13.1, “SELECT ... INTO Statement”.

  • 如果你在使用页面或行锁的存储引擎中使用 FOR UPDATE,查询检查的行会被写入锁定,直到当前事务结束。 If you use FOR UPDATE with a storage engine that uses page or row locks, rows examined by the query are write-locked until the end of the current transaction.

    你不能使用FOR UPDATE作为SELECT中的一部分,如语句CREATE TABLE new_table SELECT ... FROM old_table ...。 (如果你尝试这样做,语句会被拒绝并显示错误无法在创建old_table时更新表 'new_table' is being created.)You cannot use FOR UPDATE as part of the SELECT in a statement such as CREATE TABLE new_table SELECT ... FROM old_table .... (If you attempt to do so, the statement is rejected with the error Can't update table 'old_table' while 'new_table' is being created.)

    FOR SHARE 和 LOCK IN SHARE MODE 设置共享锁,允许其他事务读取检查的行,但不能更新或删除它们。FOR SHARE 和 LOCK IN SHARE MODE 是等价的。然而,FOR SHARE,就像 FOR UPDATE一样,支持 FOR SHARESKIP LOCKED,以及 OF tbl_name 选项。NOWAIT 是 SHARE 模式下 LOCK IN SHARE MODE,但 LOCK IN SHARE MODE仍可向下兼容。FOR SHARE and LOCK IN SHARE MODE set shared locks that permit other transactions to read the examined rows but not to update or delete them. FOR SHARE and LOCK IN SHARE MODE are equivalent. However, FOR SHARE, like FOR UPDATE, supports NOWAIT, SKIP LOCKED, and OF tbl_name options. FOR SHARE is a replacement for LOCK IN SHARE MODE, but LOCK IN SHARE MODE remains available for backward compatibility.

    NOWAIT 会立即执行 FOR UPDATE 或 FOR SHARE 查询,如果因其他事务持有锁而无法获得行锁,则返回错误。NOWAIT causes a FOR UPDATE or FOR SHARE query to execute immediately, returning an error if a row lock cannot be obtained due to a lock held by another transaction.

    SKIP LOCKED 会导致 FOR UPDATE 或 FOR SHARE 立即执行,排除被其他事务锁定的结果集行。SKIP LOCKED causes a FOR UPDATE or FOR SHARE query to execute immediately, excluding rows from the result set that are locked by another transaction.

    NOWAIT 和 SKIP LOCKED 选项对基于语句的复制不安全。NOWAIT and SKIP LOCKED options are unsafe for statement-based replication.

    Note

    跳过锁定行的查询会返回数据视图不一致。SKIP LOCKED 因此不适合一般事务工作。不过,当多个会话访问同一个类似队列的表时,它可以用于避免锁的争夺。Queries that skip locked rows return an inconsistent view of the data. SKIP LOCKED is therefore not suitable for general transactional work. However, it may be used to avoid lock contention when multiple sessions access the same queue-like table.

    OF tbl_name applies FOR UPDATE以及FOR SHARE queries to named tables. For example:OF tbl_name applies FOR UPDATE and FOR SHARE queries to named tables. For example:

    SELECT * FROM t1, t2 FOR SHARE OF t1 FOR UPDATE OF t2;
    

    当省略 OF tbl_name 时,查询块引用的所有表都会被锁定。因此,在没有 OF tbl_name 的情况下使用锁定子句并与另一个锁定子句结合使用会返回错误。在多个锁定子句中指定相同的表也会返回错误。如果在 SELECT 语句中将别名指定为表名,则锁定子句只能使用该别名。如果 SELECT 语句未显式指定别名,则锁定子句只能指定实际表名。All tables referenced by the query block are locked when OF tbl_name is omitted. Consequently, using a locking clause without OF tbl_name in combination with another locking clause returns an error. Specifying the same table in multiple locking clauses returns an error. If an alias is specified as the table name in the SELECT statement, a locking clause may only use the alias. If the SELECT statement does not specify an alias explicitly, the locking clause may only specify the actual table name.

    有关 FOR UPDATE 和 FOR SHARE 的更多信息,请参阅 第 17.7.2.4 节,“锁定读取”。有关 NOWAIT 和 SKIP LOCKED 选项的附加信息,请参阅 使用 NOWAIT 和 SKIP LOCKED 的锁定读取并发。For more information about FOR UPDATE and FOR SHARE, see Section 17.7.2.4, “Locking Reads”. For additional information about NOWAIT and SKIP LOCKED options, see Locking Read Concurrency with NOWAIT and SKIP LOCKED.

在 SELECT 关键字之后,你可以使用若干修饰符来影响语句的操作。HIGH_PRIORITY、STRAIGHT_JOIN 以及以 SQL_ 开头的修饰符是 MySQL 对标准 SQL 的扩展。Following the SELECT keyword, you can use a number of modifiers that affect the operation of the statement. HIGH_PRIORITY, STRAIGHT_JOIN, and modifiers beginning with SQL_ are MySQL extensions to standard SQL.

  • ALL 和 DISTINCT 修饰符指定是否返回重复行。ALL(默认)表示返回所有匹配行,包括重复行。DISTINCT 表示从结果集中去除重复行。两者同时指定会导致错误。DISTINCTROW 是 DISTINCT 的同义词。The ALL and DISTINCT modifiers specify whether duplicate rows should be returned. ALL (the default) specifies that all matching rows should be returned, including duplicates. DISTINCT specifies removal of duplicate rows from the result set. It is an error to specify both modifiers. DISTINCTROW is a synonym for DISTINCT.

    DISTINCT 可用于也使用 WITH ROLLUP 的查询。DISTINCT can be used with a query that also uses WITH ROLLUP.

  • HIGH_PRIORITY 使 SELECT 的优先级高于更新表的语句。你应仅对非常快速且必须立即执行的查询使用此选项。即使在表被锁定以供读取时,如果有更新语句正在等待表释放,发出的 SELECT HIGH_PRIORITY 查询仍会执行。这仅影响使用表级锁定的存储引擎(如 MyISAM、MEMORY 和 MERGE)。HIGH_PRIORITY gives the SELECT higher priority than a statement that updates a table. You should use this only for queries that are very fast and must be done at once. A SELECT HIGH_PRIORITY query that is issued while the table is locked for reading runs even if there is an update statement waiting for the table to be free. This affects only storage engines that use only table-level locking (such as MyISAM, MEMORY, and MERGE).

    HIGH_PRIORITY 不能用于 SELECT 语句,这些语句是 UNION 的一部分。HIGH_PRIORITY cannot be used with SELECT statements that are part of a UNION.

  • STRAIGHT_JOIN强制优化器按照FROM子句中列出的顺序连接表。你可以使用它来加速查询,如果优化器以非最佳顺序连接表。STRAIGHT_JOIN也可以用于table_references列表中。见第 15.2.13.2 节,“JOIN 子句”.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 nonoptimal order. STRAIGHT_JOIN also can be used in the table_references list. See Section 15.2.13.2, “JOIN Clause”.

    STRAIGHT_JOIN does not apply to any table that the optimizer treats as a const或者system table. Such a table produces a single row, is read during the optimization phase of query execution, and references to its columns are replaced with the appropriate column values before query execution proceeds. These tables appear first in the query plan displayed by EXPLAIN。参见Section 10.8.1, “Optimizing Queries with EXPLAIN”. This exception may not apply to const或者system tables that are used on the NULL-complemented side of an outer join (that is, the right-side table of a LEFT JOIN or the left-side table of a RIGHT JOIN.STRAIGHT_JOIN does not apply to any table that the optimizer treats as a const or system table. Such a table produces a single row, is read during the optimization phase of query execution, and references to its columns are replaced with the appropriate column values before query execution proceeds. These tables appear first in the query plan displayed by EXPLAIN. See Section 10.8.1, “Optimizing Queries with EXPLAIN”. This exception may not apply to const or system tables that are used on the NULL-complemented side of an outer join (that is, the right-side table of a LEFT JOIN or the left-side table of a RIGHT JOIN.

  • SQL_BIG_RESULT或 SQL_SMALL_RESULT 可以与 GROUP BY 或 DISTINCT 一起使用,分别告诉优化器该结果集有多行或较小。对于 SQL_BIG_RESULT 直接使用基于磁盘的临时表(如果创建的话),并且更倾向于排序,而不是使用带有键的临时表,GROUP BY 元素。对于 SQL_SMALL_RESULT 使用内存中的临时表来存储结果表,而不是使用排序。这通常不需要。SQL_BIG_RESULT or SQL_SMALL_RESULT can be used with GROUP BY or DISTINCT to tell the optimizer that the result set has many rows or is small, respectively. For SQL_BIG_RESULT, MySQL directly uses disk-based temporary tables if they are created, and prefers sorting to using a temporary table with a key on the GROUP BY elements. For SQL_SMALL_RESULT, MySQL uses in-memory temporary tables to store the resulting table instead of using sorting. This should not normally be needed.

  • SQL_BUFFER_RESULT 强制将结果放入临时表中。这有助于 MySQL 提前释放表锁,并在发送结果集到客户端需要较长时间的情况中有所帮助。该修饰符只能用于顶层 SELECT 语句,不能用于子查询或后续 UNIONSQL_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. This modifier can be used only for top-level SELECT statements, not for subqueries or following UNION.

  • SQL_CALC_FOUND_ROWS 告诉 MySQL 计算结果集中将有多少行,忽略任何 LIMIT 子句。行数随后可以通过 SELECT FOUND_ROWS()。参见 第 14.15 节,“信息函数”。SQL_CALC_FOUND_ROWS 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 Section 14.15, “Information Functions”.

    Note

    SQL_CALC_FOUND_ROWS查询修饰符及其配套的 FOUND_ROWS() 函数已被弃用;预计它们将在未来版本的 MySQL 中被移除。有关另一种策略的信息,请参见 FOUND_ROWS()The SQL_CALC_FOUND_ROWS query modifier and accompanying FOUND_ROWS() function are deprecated; expect them to be removed in a future version of MySQL. See the description of FOUND_ROWS() for information about an alternative strategy.

  • 描述。SQL_CACHE 和 SQL_NO_CACHE修饰符曾用于 MySQL 8.4 之前的查询缓存。查询缓存在 MySQL 8.4 中被移除。SQL_CACHE修饰符也被移除。SQL_NO_CACHE已被弃用,且无影响;预计未来 MySQL 版本会移除。The SQL_CACHE and SQL_NO_CACHE modifiers were used with the query cache prior to MySQL 8.4. The query cache was removed in MySQL 8.4. The SQL_CACHE modifier was removed as well. SQL_NO_CACHE is deprecated, and has no effect; expect it to be removed in a future MySQL release.