Spec-Zone.ru › MySQL 5.7

13.2.9 Запрос SELECT

  • 13.2.9.1 Запрос SELECT ... INTO
  • 13.2.9.2 Оператор JOIN
  • 13.2.9.3 Оператор UNION
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_name. Псевдоним используется в качестве имени столбца выражения и может использоваться в GROUP 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 table_references-клауза указывает таблицу или таблицы, из которых необходимо извлечь строки. Если вы указываете более одной таблицы, вы выполняете объединение. Сведения о синтаксисе объединения см. в Разделе 13.2.9.2, “Клауза JOIN”. Для каждой указанной таблицы вы можете указать псевдоним.

    tbl_name [[AS] alias] [index_hint]
    

    Использование подсказок индекса предоставляет оптимизатору информацию о том, как выбрать индексы во время обработки запроса. Описание синтаксиса указания этих подсказок см. в Разделе 8.9.4, “Подсказки индексов”.

    Вы можете использовать SET max_seeks_for_key=value в качестве альтернативного способа принудительного использования MySQL для предпочтения сканирования по ключу вместо сканирования по таблице. См. Раздел 5.1.7, “Системные переменные сервера”.

  • Вы можете ссылаться на таблицу в базе данных по умолчанию как 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_name AS alias_name или tbl_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_name FROM tbl_name HAVING col_name > 0;
    

    Вместо этого напишите:

    SELECT col_name FROM tbl_name WHERE col_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_count эквивалентно LIMIT 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_count OFFSET offset.

    Если 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_table SELECT ... FROM old_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_RESULT MySQL напрямую использует таблицы временного хранения на диске, если они создаются, и отдает предпочтение сортировке вместо использования временной таблицы с ключом по элементам GROUP BY. Для SQL_SMALL_RESULT MySQL использует временные таблицы в оперативной памяти для хранения результирующей таблицы вместо использования сортировки. Обычно это не требуется.

  • 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.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/select.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API