13.2.9 Запрос 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 [, select_expr] ...
[into_option]
[FROM table_references
[PARTITION partition_list]]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[into_option]
[FOR UPDATE | LOCK IN SHARE MODE]
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 и подзапросы. См. Раздел 13.2.9.3, «Оператор UNION» и Раздел 13.2.10, «Подзапросы».
Наиболее часто используемые предложения в операторах SELECT таковы:
Каждый
select_exprуказывает столбец, который нужно извлечь. Должен быть хотя бы одинselect_expr.table_referencesуказывает таблицу или таблицы, из которых нужно извлечь строки. Его синтаксис описан в Разделе 13.2.9.2, «Оператор JOIN».-
SELECTподдерживает явное выборку разделов, используя предложениеPARTITIONсо списком разделов или подразделов (или того и другого) после имени таблицы вtable_reference(см. Раздел 13.2.9.2, «Оператор JOIN»). В этом случае строки выбираются только из указанных разделов, а все остальные разделы таблицы игнорируются. Более подробную информацию и примеры см. в Разделе 22.5, «Выбор разделов».SELECT ... PARTITIONиз таблиц с помощью таких механизмов хранения, какMyISAM, которые выполняют блокировку таблицы (а значит, и разделов), блокируют только указанные предложениемPARTITIONразделы или подразделы.Более подробную информацию см. в Разделе 22.6.4, «Разбиение и блокировка».
-
Предложение
WHERE, если задано, указывает условие или условия, которым должны удовлетворять строки для выбора.where_condition— выражение, которое вычисляется как истина для каждой строки, подлежащей выбору. Если предложениеWHEREотсутствует, запрос выбирает все строки.В выражении
WHEREможно использовать любые функции и операторы, поддерживаемые MySQL, за исключением агрегирующих (групповых) функций. См. Раздел 9.5, «Выражения» и Главу 12, Функции и операторы.
SELECT также можно использовать для получения строк, вычисленных без ссылки на таблицу.
Например:
mysql> SELECT 1 + 1;
-> 2
Разрешается указывать DUAL в качестве псевдонима таблицы в ситуациях, когда таблицы не упоминаются:
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
DUAL предназначено только для удобства пользователей, которым требуется, чтобы все SELECT операторы содержали FROM и, возможно, другие предложения. MySQL может игнорировать эти предложения. MySQL не требует FROM DUAL, если таблицы не упоминаются.
В общем случае, предложения должны быть указаны в том же порядке, что и в описании синтаксиса. Например, предложение HAVING должно следовать за предложением GROUP BY и предшествовать предложению ORDER
BY. Если присутствует предложение INTO, оно может находиться в любом положении, указанном в описании синтаксиса, но в рамках одного оператора может появиться только один раз, а не в нескольких местах. Дополнительную информацию о INTO см. в Разделе 13.2.9.1, «Запрос SELECT ... INTO».
Список select_expr терминов образует список выбора, который указывает, какие столбцы нужно извлечь. Термины указывают столбец или выражение или используют *-сокращение:
-
Список выбора, состоящий только из одного неопределенного
*, может использоваться как сокращение для выбора всех столбцов из всех таблиц:SELECT * FROM t1 INNER JOIN t2 ...
-
можно использовать как сокращение для выбора всех столбцов из указанной таблицы:tbl_name.*SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...
-
Использование неопределенного
*с другими элементами в списке выбора может привести к ошибке анализа. Например:SELECT id, * FROM t1
Чтобы избежать этой проблемы, используйте квалифицированную ссылку на
:tbl_name.*SELECT id, t1.* FROM t1
Используйте квалифицированные ссылки
для каждой таблицы в списке выбора:tbl_name.*SELECT AVG(score), t1.* FROM t1 ...
Следующий список предоставляет дополнительную информацию об остальных SELECT предложениях:
-
Можно присвоить псевдоним
select_exprс помощьюAS. Псевдоним используется в качестве имени столбца выражения и может использоваться вalias_nameGROUP BY,ORDER BYилиHAVING-клаузах. Например:SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
Ключевое слово
ASнеобязательно при присвоении псевдонимаselect_exprс помощью идентификатора. Предыдущий пример можно было бы записать так:SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;
Однако, поскольку ключевое слово
ASнеобязательно, может возникнуть проблема, если вы забудете запятую между двумя выражениямиselect_expr: MySQL интерпретирует второе выражение как имя псевдонима. Например, в следующем оператореcolumnbинтерпретируется как имя псевдонима:SELECT columna columnb FROM mytable;
По этой причине рекомендуется всегда явно указывать псевдонимы столбцов с помощью
AS.Ссылаться на псевдоним столбца в
WHERE-клаузе недопустимо, потому что значение столбца может ещё не быть определено во время выполненияWHERE-клаузы. См. Раздел B.3.4.4, “Проблемы с псевдонимами столбцов”. -
FROM-клауза указывает таблицу или таблицы, из которых необходимо извлечь строки. Если вы указываете более одной таблицы, вы выполняете объединение. Сведения о синтаксисе объединения см. в Разделе 13.2.9.2, “Клауза JOIN”. Для каждой указанной таблицы вы можете указать псевдоним.table_referencestbl_name[[AS]alias] [index_hint]Использование подсказок индекса предоставляет оптимизатору информацию о том, как выбрать индексы во время обработки запроса. Описание синтаксиса указания этих подсказок см. в Разделе 8.9.4, “Подсказки индексов”.
Вы можете использовать
SET max_seeks_for_key=в качестве альтернативного способа принудительного использования MySQL для предпочтения сканирования по ключу вместо сканирования по таблице. См. Раздел 5.1.7, “Системные переменные сервера”.value Вы можете ссылаться на таблицу в базе данных по умолчанию как
tbl_nameили какdb_name.tbl_name, чтобы явно указать базу данных. Вы можете ссылаться на столбец какcol_name,tbl_name.col_nameилиdb_name.tbl_name.col_name. Необязательно указывать префиксtbl_nameилиdb_name.tbl_nameдля ссылки на столбец, если ссылка не является неоднозначной. Примеры неоднозначных случаев, требующих более явных форм ссылок на столбец, см. в Разделе 9.2.2, “Квалификаторы идентификаторов”.-
Ссылку на таблицу можно снабдить псевдонимом с помощью
илиtbl_nameASalias_nametbl_name alias_name. Эти утверждения эквивалентны: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: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(descending) к имени столбца вORDER BY-клаузе, по которому производится сортировка. По умолчанию используется возрастающий порядок; это можно явно указать, используя ключевое словоASC.Если
ORDER BYвстречается внутри скобочного выражения запроса и также используется во внешнем запросе, результаты будут неопределёнными и могут измениться в будущих версиях MySQL.Использование позиций столбцов устарело, так как синтаксис был удалён из стандарта SQL.
MySQL расширяет
GROUP BY-клаузу, позволяя также указыватьASCиDESCпосле названий столбцов в данной клаузе. Однако этот синтаксис устарел. Для получения заданного порядка сортировки используйтеORDER BY-клаузу.-
Если вы используете
GROUP BY, строки вывода сортируются поGROUP BYстолбцам так, как если бы у вас былаORDER BYдля тех же столбцов. Чтобы избежать накладных расходов на сортировку, производимуюGROUP BY, добавьтеORDER BY NULL:SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;
Использование неявной сортировки по
GROUP BY(т. е. сортировка в отсутствиеASCилиDESC) или явной сортировки поGROUP BY(т. е. с использованием явныхASCилиDESCдляGROUP BY) устарело. Для получения заданного порядка сортировки используйтеORDER BY-клаузу. При использовании
ORDER BYилиGROUP BYдля сортировки столбца вSELECT, сервер сортирует значения, используя только начальное количество байтов, указанное системной переменнойmax_sort_length.MySQL расширяет использование
GROUP BY, позволяя выбирать поля, которые не упоминаются вGROUP BY-клаузе. Если вы не получаете ожидаемых результатов от своего запроса, прочитайте описаниеGROUP BYв Разделе 12.19, “Функции агрегирования”.GROUP BYдопускает модификаторWITH ROLLUP. См. Раздел 12.19.2, “Модификаторы GROUP BY”.-
HAVING-клауза, как иWHERE-клауза, определяет условия выбора.WHERE-клауза задаёт условия для столбцов в списке выбора, но не может ссылаться на агрегатные функции.HAVING-клауза задаёт условия для групп, обычно формируемыхGROUP BY-клаузой. Результат запроса включает только группы, удовлетворяющие условиямHAVING. (ЕслиGROUP BYотсутствует, все строки неявно образуют одну агрегированную группу.)HAVING-клауза применяется почти последней, непосредственно перед отправкой элементов клиенту, без оптимизации. (LIMITприменяется послеHAVING.)Стандарт SQL требует, чтобы
HAVINGссылалась только на столбцы вGROUP BY-клаузе или столбцы, используемые в агрегатных функциях. Однако MySQL поддерживает расширение этого поведения и допускает, чтоHAVINGможет ссылаться на столбцы в спискеSELECTи столбцы во внешних подзапросах.Если
HAVING-клауза ссылается на неоднозначный столбец, возникает предупреждение. В следующем оператореcol2неоднозначен, потому что используется как псевдоним и имя столбца:SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
Предпочтение отдаётся стандартному поведению SQL, поэтому если имя столбца
HAVINGиспользуется как вGROUP BY, так и в качестве алиасированного столбца в списке столбцов выбора, предпочтение отдаётся столбцу вGROUP BY-списке. -
Не используйте
HAVINGдля элементов, которые должны быть вWHERE-клаузе. Например, не пишите следующее:SELECT
col_nameFROMtbl_nameHAVINGcol_name> 0;Вместо этого напишите:
SELECT
col_nameFROMtbl_nameWHEREcol_name> 0; -
HAVING-клауза может ссылаться на агрегатные функции, которыхWHERE-клауза не может:SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary) > 10;
(Это не работало в некоторых более старых версиях MySQL.)
-
MySQL допускает дублирование имён столбцов. То есть может быть более одного
select_exprс одинаковым именем. Это расширение стандарта SQL. Поскольку MySQL также позволяетGROUP BYиHAVINGссылаться наselect_exprзначения, это может привести к неоднозначности:SELECT 12 AS a, a FROM t GROUP BY a;
В этом операторе оба столбца имеют имя
a. Чтобы убедиться, что используется правильный столбец для группировки, используйте разные имена для каждогоselect_expr. MySQL разрешает ссылки на неопределённые столбцы или псевдонимы в
ORDER BY-клаузах, сначала в значенияхselect_expr, затем в столбцах таблиц вFROM-клаузе. ДляGROUP BYилиHAVING-клауз поиск осуществляется вFROM-клаузе перед поиском в значенияхselect_expr. (ДляGROUP BYиHAVINGэто отличается от поведения до MySQL 5.0, которое использовало те же правила, что и дляORDER BY.)
-
Оператор
LIMITможет использоваться для ограничения количества строк, возвращаемых операторомSELECT. ОператорLIMITпринимает один или два числовых аргумента, которые должны быть неотрицательными целочисленными константами, за исключением следующих случаев:В подготовленных операторах параметры
LIMITмогут быть указаны с помощью маркеров замещения?.В хранимых программах параметры
LIMITмогут быть указаны с использованием целочисленных параметров процедуры или локальных переменных.
При использовании двух аргументов, первый аргумент задает смещение первой строки для возврата, а второй - максимальное количество строк для возврата. Смещение начальной строки равно 0 (а не 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
Для получения всех строк с определенного смещения до конца набора результатов можно использовать большое число для второго параметра. Данный оператор получает все строки с 96-й строки до последней:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
При использовании одного аргумента, значение указывает количество строк для возврата с начала набора результатов:
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
Другими словами,
LIMITэквивалентноrow_countLIMIT 0,.row_countДля подготовленных операторов можно использовать маркеры замещения. Следующие операторы возвращают одну строку из таблицы
tbl:SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;
Следующие операторы возвращают вторую по шестую строки из таблицы
tbl:SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;
Для совместимости с PostgreSQL, MySQL также поддерживает синтаксис
LIMIT.row_countOFFSEToffsetЕсли
LIMITиспользуется внутри выражения запроса в скобках, а также применяется во внешнем запросе, результаты будут неопределенными и могут измениться в будущей версии MySQL. -
Оператор
PROCEDUREзадаёт процедуру, которая должна обработать данные в наборе результатов. Пример смотрите в разделе 8.4.2.4, «Использование PROCEDURE ANALYSE», который описываетANALYSE, процедуру, которая может быть использована для получения рекомендаций по оптимальным типам данных столбцов, которые могут помочь уменьшить размер таблицы.Оператор
PROCEDUREне разрешён в оператореUNION.ПримечаниеСинтаксис
PROCEDUREустарел начиная с MySQL 5.7.18 и удалён в MySQL 8.0. Форма оператора
SELECT ... INTOоператораSELECTпозволяет записывать результаты запроса в файл или сохранять их в переменные. Дополнительная информация в разделе 13.2.9.1, «SELECT ... INTO Statement».-
Если вы используете
FOR UPDATEс хранилищем, которое использует страничные или строковые блокировки, строки, просмотренные запросом, будут заблокированы на запись до конца текущей транзакции. ИспользуяLOCK IN SHARE MODE, устанавливается общая блокировка, которая позволяет другим транзакциям читать просмотренные строки, но не обновлять или удалять их. См. раздел 14.7.2.4, «Блокировка чтений».Кроме того, вы не можете использовать
FOR UPDATEв качестве части оператораSELECTв операторе, таком какCREATE TABLE. (Если вы попытаетесь это сделать, оператор будет отклонен с ошибкой Невозможно обновить таблицу 'new_tableSELECT ... FROMold_table...old_table' в то время как 'new_table' создается). Это изменение поведения по сравнению с MySQL 5.5 и более ранними версиями, которые разрешали операторамCREATE TABLE ... SELECTвносить изменения в таблицы, отличные от таблицы, которая создаётся.
После ключевого слова SELECT можно использовать несколько модификаторов, которые влияют на работу оператора. HIGH_PRIORITY, STRAIGHT_JOIN и модификаторы, начинающиеся с SQL_, являются расширениями MySQL для стандартного SQL.
-
Модификаторы
ALLиDISTINCTуказывают, должны ли возвращаться дублированные строки.ALL(по умолчанию) указывает, что должны возвращаться все соответствующие строки, включая дубликаты.DISTINCTуказывает на удаление дубликатов строк из набора результатов. Запрещается указывать оба модификатора.DISTINCTROWявляется синонимом дляDISTINCT. -
HIGH_PRIORITYпридаёт операторуSELECTболее высокий приоритет, чем оператору, обновляющему таблицу. Вы должны использовать это только для очень быстрых запросов, которые должны быть выполнены сразу. ЗапросSELECT HIGH_PRIORITY, который выполняется, в то время как таблица заблокирована для чтения, выполняется даже если есть оператор обновления, ожидающий освобождения таблицы. Это влияет только на хранилища, которые используют только блокировку на уровне таблицы (например,MyISAM,MEMORYиMERGE).HIGH_PRIORITYнельзя использовать с операторамиSELECT, которые являются частьюUNION. -
STRAIGHT_JOINзаставляет оптимизатор объединять таблицы в том порядке, в котором они перечислены в оператореFROM. Вы можете использовать это для ускорения запроса, если оптимизатор объединяет таблицы в неоптимальном порядке.STRAIGHT_JOINтакже может использоваться в спискеtable_references. См. раздел 13.2.9.2, «Оператор JOIN».STRAIGHT_JOINне применяется к любой таблице, которую оптимизатор обрабатывает как таблицуconstилиsystem. Такая таблица генерирует одну строку, читается во время фазы оптимизации выполнения запроса и ссылки на её столбцы заменяются соответствующими значениями столбцов до продолжения выполнения запроса. Эти таблицы появляются первыми в плане запроса, отображаемом операторомEXPLAIN. См. раздел 8.8.1, «Оптимизация запросов с помощью EXPLAIN». Это исключение может не применяться к таблицамconstилиsystem, которые используются со стороны, дополняющейNULL, внешнего соединения (то есть правая таблицаLEFT JOINили левая таблицаRIGHT JOIN). -
SQL_BIG_RESULTилиSQL_SMALL_RESULTмогут быть использованы сGROUP BYилиDISTINCT, чтобы указать оптимизатору, что набор результатов содержит много строк или является небольшим, соответственно. ДляSQL_BIG_RESULTMySQL напрямую использует таблицы временного хранения на диске, если они создаются, и отдает предпочтение сортировке вместо использования временной таблицы с ключом по элементамGROUP BY. ДляSQL_SMALL_RESULTMySQL использует временные таблицы в оперативной памяти для хранения результирующей таблицы вместо использования сортировки. Обычно это не требуется. -
SQL_BUFFER_RESULTзаставляет результат помещаться во временную таблицу. Это помогает MySQL освободить блокировки таблиц раньше и помогает в случаях, когда долгое время передается набор результатов клиенту. Этот модификатор может быть использован только для операторовSELECTверхнего уровня, а не для подзапросов или послеUNION. -
SQL_CALC_FOUND_ROWSсообщает MySQL вычислить количество строк в наборе результатов, игнорируя любой операторLIMIT. Количество строк можно получить с помощьюSELECT FOUND_ROWS(). См. раздел 12.15, «Функции информации». -
Модификаторы
SQL_CACHEиSQL_NO_CACHEвлияют на кэширование результатов запросов в кэше запросов (см. раздел 8.10.3, «Кэш запросов MySQL»).SQL_CACHEсообщает MySQL сохранить результат в кэше запросов, если он кэшируется, а значение системной переменнойquery_cache_typeравно2илиDEMAND. СSQL_NO_CACHEсервер не использует кэш запросов. Он не проверяет кэш запросов, чтобы увидеть, уже ли результат кэширован, и не кэширует результат запроса.Эти два модификатора взаимно исключают друг друга, и возникает ошибка, если они оба указаны. Также эти модификаторы не разрешены в подзапросах (включая подзапросы в операторе
FROM) и операторахSELECTв объединениях, кроме первого оператораSELECT.Для представлений,
SQL_NO_CACHEприменяется, если оно появляется в любом оператореSELECTв запросе. Для кэшируемого запросаSQL_CACHEприменяется, если оно появляется в первом оператореSELECTпредставления, на которое ссылается запрос.ПримечаниеКэш запросов устарел начиная с MySQL 5.7.20 и удалён в MySQL 8.0. К устареванию относятся
SQL_CACHEиSQL_NO_CACHE.
A SELECT from a partitioned table using a storage engine such as MyISAM that employs table-level locks locks only those partitions containing rows that match the SELECT statement WHERE clause. (This does not occur with storage engines such as InnoDB that employ row-level locking.) For more information, see Section 22.6.4, “Partitioning and Locking”.
© 2025 Oracle
Licensed under the GPLv2 License.