Поиск

Синтаксис 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] выражение_Бе1ес1, ... [INTO OUTFILE 'имя_файла*опции_экспорта
I INTO DUMPFILE ' имя_файла} } [FROM табличные_ссылки
[WHERE олределеяие_where]
[GROUP BY {имя_столбца выражение позиция} [ASC | DESCJ, ... [WITH ROLLUP]]
[HAVING onpsuejssHKS_wheze)
[ORDER BY {имя_столбца выражение позиция] [ASC | DESC] ,...]
[LIMIT [смещение, {] количество_строк | количество_строк OFFSET смещение}]
[PROCEDURE имя_процедуры(список_аргументов) ]
[FOR UPDATE | LOCK IN SHARE MODE]]
SELECT применяется для извлечения строк из одной или более таблиц. Поддержка операторов UNION и подзапросов доступна, начиная с версий MySQL 4.0 и 4.1, соответст­венно. См. разделы Синтаксис UNION и Синтаксис подзапросов

  • Каждое выражение выражение_зе1есЬ указывает столбец, который необходимо извлечь.
    табличные_ссылки указывают таблицу или таблицы, из которых извлекаются строки. Соответствующий синтаксис описан в разделе Синтаксис подзапросов

  • определение^/]еге задает любые условия, которым должны удовлетворять выбранные строки.
    SELECT также может использоваться для извлечения вычисляемых строк без обраще­ния к какой-либо таблице. Например:
    mysql> SELECT 1 + 1; -> 2
    Все используемые в операторе конструкции даются точно в том порядке, как приве­дено в описании синтаксиса. Например, конструкция HAVING должна следовать за конст­рукцией GROUP BY И перед ORDER BY.
  • Выражению выражение_зе1есЬ может быть дан псевдоним as имя_псевдонима.
Псевдоним используется как имя столбца, заданного выражением, и может присутствовать в конструкциях GROUP BY, ORDER BY и HAVING, например:
mysql> SELECT CONCAT (last_name,', ',first name) AS full_name -> ИЮТ mytable ORDER BY full_name;
При присвоении псевдонима столбцу указывать ключевое слово AS не обязатель­но. Предыдущий пример может быть переписан следующим образом:
mysql> SELECT CONCAT(last_name,', ',first jiame) full name -> FROM mytable ORDER BY fulljiame;
Поскольку AS необязательно, здесь может возникнуть одна тонкая проблема, если вы забудете поставить запятую между двумя выражениями SELECT: MySQL ин­терпретирует второе как псевдоним. Например, в следующем операторе columnb рассматривается как псевдоним: mysql> SELECT columna columnb FROM mytable;

  1. He допускается указание псевдонима столбца в конструкции WHERE, поскольку значение столбца еще может быть неопределенным, когда выполняется конструкция WHERE. См. раздел Проблемы с псевдонимами столбцов
  2. Конструкция FROM табличные_ссылки перечисляет таблицы, из которых извлекаются строки. Если вы указываете более чем одну таблицу, выполняется соединение. Информацию о синтаксисе соединений можно найти в разделеСинтаксис JOIN Для каждой из перечисленных таблиц можно указать необязательный псевдоним.

имя_таблицы [ [AS] псевдоним] [[USE INDEX {список_ключей) ]
I [IGNORE INDEX {список_ключей) ] | [FORCE INDEX {список_ключей)]]
Применение USE INDEX, IGNORE INDEX, FORCE INDEX для указания подсказок опти­мизатору по использованию индексов описано в разделе 6.1.7.1. Начиная с MySQL 4.0.14, можно использовать SET max_seeks_for_key= 3Ha4eHne, как альтернативный способ заставить MySQL предпочесть поиск по ключу вместо сканирования таблицы.

  • К таблице внутри текущей базы данных можно обращаться как имя__ таблицы, либо как имя_базы_данных.имя_таблицы для явного указания базы данных. Вы можете сослаться на столбец как имя столбца, имя таблицы,имя столбца или имя_базы_данных.имя_таблицы.имя_столбца. Префиксы столбцов имя_таблицы или имя_базы_данных.имя__таблицы указывать необязательно, если только ссылка на столбец не является неоднозначной. В разделе Имена баз данных, таблиц, индексов, столбцов и псевдонимов представлены примеры неодно­значных ссылок, которые требуют более явных спецификаций.
  • Начиная с MySQL 4.1.0, допускается указывать DUAL как имя псевдотаблицы в ситуациях, когда не нужны ссылки на реальные таблицы:
    mysql> SELECT 1+1 FROM DUAL; -> 2
    DUAL введено исключительно совместимости ради. Некоторые другие серверы баз данных требуют такого синтаксиса.
  • Ссылка на таблицу может быть заменена псевдонимом: имя_таблицы [AS]
    имя псевдонима.
mysql> SELECT tl.name, t2.salary FROM employee AS tl, info AS t2
-> WHERE tl.name = t2.name; mysql> SELECT tl.name, t2.salary FROM employee tl, info t2
-> WHERE tl.name = t2.name;

  1. В конструкции WHERE можно использовать любые функции, поддерживаемые MySQL, за исключением агрегатных (итоговых) функций. См. главу Функции и операции
  2. На столбцы, выбранные для вывода, можно ссылаться в конструкциях ORDER BY и GROUP BY, используя при этом имена столбцов, псевдонимы столбцов либо их номера позиций. Позиции столбцов указываются целыми числами, начиная с 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;
Чтобы сортировать в обратном порядке, в конструкции ORDER BY потребуется до­бавить ключевое слово DESC к имени столбца, по которому выполняется сорти­ровка. По умолчанию применяется порядок сортировки по возрастанию. Это можно указать явно ключевым словом ASС.
Применение номеров позиций столбцов считается устаревшим, поскольку этот синтаксис исключен из стандарта SQL.

  • Если используется GROUP BY, выходные строки сортируются в соответствии со столбцами, указанными в GROUP BY, как если бы было указано ORDER BY для тех же столбцов. MySQL имеет расширенный вариант конструкции GROUP BY, начиная с версии сервера 3.23.34, позволяющий специфицировать ASC и DESC после столбцов, названных в конструкции: SELECT a, COUNT (b) FROM test_table GROUP BY a DESC
  • MySQL расширяет применение GROUP BY, позволяя выбирать поля, не перечисленные в конструкции GROUP BY. Если вы не получаете ожидаемого результата на запрос, прочтите описание использования GROUP BY в разделеФункции и модификаторы, применяемые в конструкции GROUP BY
    1. >Начиная с MySQL 4.1.1, GROUP by допускает модификатор WITH ROLLUP. См. раздел Функции и модификаторы, применяемые в конструкции GROUP BY.
    2. Конструкция HAVING может ссылаться на любой столбец или псевдоним из выражение_ге1ес1. Оно указывается почти в конце, непосредственно перед отправкой результата клиенту, без оптимизации (только LIMIT находится после HAVING).
    3. Не используйте HAVING для элементов, которые должны быть в конструкции WHERE. Например, не делайте так:

    mysql> SELECT имя_столбца FROM имя_таблицы HAVING имя_столбца > 0;
    Вместо этого лучше написать:
    mysql> SELECT имя_столбца FROM имя_таблицы WHERE имя_столбца > 0;

    • Конструкция HAVING может ссылаться на агрегатные функции, в то время как
      WHERE - нет:
      mysql> SELECT user, MAX(salary) FROM users -> GROUP BY user HAVING MAX(salary)>10;
      Однако это не работает в старых версиях MySQL (до 3.22.5). Вместо этого вы мо­жете использовать псевдоним в списке выбираемых столбцов, чтобы сослаться на него в конструкции HAVING:
      mysql> SELECT user, MAX(salary) AS max salary FROM users -> GROUP BY user HAVING max_salary>10;
      • Конструкция LIMIT может использоваться для ограничения количества строк, воз­вращаемых оператором SELECT. LIMIT принимает один или два числовых аргумен­та, которые должны быть целочисленными константами. Когда указываются два аргумента, первый означает смещение в результирующем списке первой строки, которую нужно вернуть, а второй — максимальное количество возвращаемых строк. Смещение начальной строки равно 0 (не 1): mysql> SELECT * FROM table LIMIT 5ДО; # Извлечение строк 6-15
      Для совместимости с PostgreSQL система MySQL также поддерживает синтаксис LIMIT количество_строк OFFSET смещение.
      Чтобы извлечь все строки, начиная с определенного смещения и до конца резуль­тирующего набора, можно использовать какое-нибудь большое число во втором параметре. Этот оператор извлекает все строки, начиная с 96-й и до последней: mysql> SELECT * FROM table LIMIT 95,18446744073709551615;
      Если указан один аргумент, то он обозначает количество строк, которые нужно
      вернуть от начала результирующего набора:
      mysql> SELECT * FROM table LIMIT 5; # Извлечь первые 5 строк
      Другими словами, LIMIT л эквивалентно LIMIT 0fл.
    • Синтаксис select. ..into OUTFILE 'имя_файла* пишет извлекаемые строки в файл. Файл создается на хосте сервера, поэтому вы должны иметь привилегию FILE, чтобы использовать эту форму SELECT. Файл не должен существовать на момент выполнения оператора, что предотвращает случайное разрушение важных системных файлов, вроде /etc/passwd или файлов таблиц.

    Оператор SELECT... INTO OUTFILE предназначен главным образом для того, чтобы позволять быстро выгружать дамп таблицы на машине сервера. Если вы хотите создать результирующий файл на хосте клиента, вы не можете применить для этого SELECT.. .INTO OUTFILE. В этом случае вы должны вместо этого использо­вать на клиентской машине что-то вроде mysql -e "SELECT..." > имя_ файла для генерации файла.
    SELECT.. .INTO OUTFILE - это дополнение LOAD DATA INFILE. Синтаксис части опции_экспорта этого оператора состоит из тех же предложений FIELDS и LINES, которые применяются в LOAD DATA INFILE. См. раздел 6.1.5. FIELDS ESCAPED BY управляет записью специальных символов. Если аргумент FIELDS ESCAPED BY не пуст, он используется в качестве префикса при выводе сле­дующих символов:

    1. Самого символа FIELDS ESCAPED BY.
    2. Символа FIELDS [OPTIONALLY] ENCLOSED BY.
    3. Первого символа значений FIELDS TERMINATED BY И LINES TERMINATED BY.
    4. ASCII 0 (который пишется вслед за символом отмены как ASCII '0', а не нулевой байт).

    Если FIELDS ESCAPED BY пуст, никакие символы не предваряются символами от­мены, и NULL выводится как NULL, а не N. Вероятно, это не очень хорошая идея -указывать пустой символ отмены, особенно, если значения полей в ваших данных содержат любые из перечисленных выше символов.
    Причина этого состоит в том, что вы обязаны предварять символами отмены любые СИМВОЛЫ ИЗ FIELDS TERMINATED BY, ENCLOSED BY, ESCAPED BY И LINES TERMINATED BY, чтобы гарантированно иметь возможность прочесть файл в буду­щем. ASCII NUL предваряется символом отмены для того, чтобы упростить про­смотр файла некоторыми программами постраничного вывода. Результирующий файл не должен соответствовать SQL-синтаксису, поэтому ни­чего другого более не должно предваряться символами отмены. Ниже приведен пример, который генерирует файл в формате с запятой в качестве разделителя полей, который используется многими программами:
    SELECT a,b,a+b INTO OUTFILE '/tmp/result.text' FIELDS TERMINATED BY f,' OPTIONALLY ENCLOSED BY ""' LINES TERMINATED BY 'n' FROM test_table;

    1. Если вы используете INTO DUMPFILE вместо INTO OUTFILE, MySQL пишет только одну строку в файл, без каких-либо ограничителей строк или столбцов, без какой бы то ни было обработки с помощью символов отмены. Это удобно, если нужно поместить в файл значения типа BLOB.
    2. Следует отметить, что любой файл, созданный into DUMPFILE или INTO OUTFILE, доступен по записи всем пользователям хоста сервера. Причина этого в том, что сервер MySQL не может создать файл, принадлежащий кому-нибудь другому, а не пользователю, от имени которого он запущен (никогда не запускайте mysqld от имени root). Поэтому файл должен быть доступным всем по записи, чтобы вымогли манипулировать его содержимым.
    3. Конструкция PROCEDURE определяет процедуру, которая должна обрабатывать данные в результирующем наборе.
    4. Если вы применяете FOR UPDATE с механизмом хранения, который использует блокировки страниц или строк, то строки, проверяемые запросом, блокируются по записи до завершения текущей транзакции.

    После ключевого слова SELECT можно указать множество опций, влияющих на вы­полнение оператора.
    Опции ALL, DISTINCT и DISTINCTROW определяют, должны ли возвращаться дублиро­ванные строки. Если ни одна из этих опций не указана, по умолчанию принимается all (возвращаются все соответствующие строки). DISTINCT и DISTINCTROW - синонимы; они указывают, что дублированные строки в результирующем наборе исключаются.
    HIGH_PRIORITY, STRAIGHT_JOIN и опции, начинающиеся с SQL_, являются расшире­ниями MySQL стандарта SQL.

    1. HIGH_PRIORITY назначает оператору SELECT более высокий приоритет, чем операторам обновления таблицы. Вы должны использовать это только для запросов, которые выполняются однократно и очень быстро. Запрос SELECT HIGHPRIORITY, отправленный, когда таблица заблокирована по чтению, будет выполняться, даже если есть ожидающий освобождения таблицы оператор обновления данных. high_priority не может использоваться с оператором select, являющимся частью UNION.
    2. STRAIGHT_JOIN заставляет оптимизатор объединять таблицы в том порядке, в котором они перечислены в конструкции FROM. Это можно использовать для ускорения запросов, когда оптимизатор объединяет таблицы не в оптимальном порядке.STRAIGHT_JOIN также может применяться в списке табличные_ссилки. См. раздел Синтаксис JOIN
    3. SQL_BIG_RESULT может применяться с GROUP BY или DISTINCT, чтобы сообщить оптимизатору, что результирующий набор будет иметь много строк. В этом случае MySQL будет непосредственно использовать при необходимости временные таблицы на диске. А также в этом случае MySQL предпочтет сортировку по ключу элементов GROUP BY с использованием временных таблиц.
    4. SQL_BUFFER_RESULT принудительно помещает результат во временный файл. Это помогает MySQL пораньше освободить табличные блокировки и оказывается полезным в случаях, когда на отправку результирующего набора клиенту тратится много времени.
    5. SQL_SMALL_RESULT может применяться вместе с GROUP BY или DISTINCT, чтобы со общить оптимизатору, что результирующий набор будет маленьким. В этом случае MySQL использует быстрые временные таблицы, чтобы хранить результирующую таблицу вместо применения сортировки. В MySQL 3.23 и выше это обычно не требуется.
    6. SQL CALC_FOUND_ROWS (доступно в MySQL 4.0.0 и выше) сообщает серверу MySQL, что нужно посчитать количество строк в результирующем наборе, независимо от конструкции LIMIT. Количество строк затем может быть извлечено с помощью SELECT FOUND_ROWS(). См. раздел Информационные функции

    До MySQL 4.1.0 эта опция не работала с LIMIT 0, что было оптимизировано для немедленного возврата (со значением счетчика строк, равным 0).

      • SQL_CACHE заставляет MySQL сохранять результат в кэше запросов, если используется значение query_cache_type, равное 2, или DEMAND. Для запросов, использующих UNION или подзапросы, эта опция влияет на все операторы SELECT в запросе.
      • SQL_NO_CACHE сообщает MySQL, что результаты запросов не нужно сохранять в кэше. Для запросов, которые используют UNION или подзапросы, эта опция влияет на все операторы SELECT в запросе.

Синтаксис JOIN
MySQL поддерживает следующие варианты синтаксиса JOIN в части таблич-ныеjcсилки операторов SELECT, а также многотабличных операторов DELETE и UPDATE:
табличная_ссылка, табличная_ссылка
табличная_ссылка [INNER | CROSS] табличная_ссылка [условие_соединения]
табличная_ссылка STRAIGHT_JOIN табличная^ссылка
табличная_ссылка LEFT [OUTER] JOIN табличная_ссылка [условие_соединения]
табличная_ссылкаNATURAL [LEFT [OUTER]] JOIN табличная_ ссылка
{ OJ табличная_ссылка LEFT OUTER JOIN табличная_ссылкаON условное_выражение}
табличная_ссылка RIGHT [OUTER] JOIN табличнаяссылка [условиесоединения]
табличная_ссылкаNATURAL [RIGHT [OUTER]] JOIN табличная_ссылка
табличная_ссылка определено как:
имя_таблицы [[AS] псевдоним] [[USE INDEX {список_ключей) ]
[IGNORE INDEX {список__ключей) ] [FORCE INDEX {список_ключей)]]
условие_соединения определено как:
ON условное_выражение | USING (список_столбцов)
Обычно вы не должны иметь в части ON никаких условий, ограничивающих строки для результирующего набора. Эти условия указываются в конструкции WHERE.
Однако существуют исключения их этого правила.
Отметим, что синтаксис INNER JOIN предусматривает условие_соединения только на­чиная с версии MySQL 3.23.17 и выше. То же самое верно и для JOIN и CROSS JOIN, но только начиная с версии MySQL 4.0.11.
Синтаксис {OJ...LEFT OUTER JOIN...}, представленный выше, введен только для совместимости с ODBC.
  • Ссылки на таблицы могут быть заменены псевдонимами с использованием имя_таблицы AS имя_псевдонима или имятаблицы имя_псевдонима:
    mysql> SELECT tl.name, t2.salary FROM employee AS tl, info AS t2
    -> WHERE tl.name = t2.name; mysql> SELECT tl.name, t2.salary FROM employee tl, info t2
    -> WHERE tl.name = t2.name;
  • Условия ON - это любые условные выражения в той же форме, что применяются в конструкции WHERE.
  • Если не найдено соответствующих записей в правой таблице части ON или USING конструкции LEFT JOIN, для правой таблицы используется строка со всеми столбцами, установленными в NULL. Этим фактом можно воспользоваться для поиска записей в таблице, для которой не существует дополнений в другой таблице:
    mysql> SELECT tablel.* FROM tablel
    -> LEFT JOIN table2 ON tablel.id=table2.id -> WHERE table2.id IS NULL;
    Этот пример находит все строки таблицы tablel со значениями id, которых нет в таблице table2 (то есть, всех строк таблицы tablel, для которых нет связанных строк в table2). Предполагается, что table2. id объявлен как NOT NULL.
  • Конструкция USING{список_столбцов) перечисляет список столбцов, которые должны присутствовать в обеих таблицах. Следующие две конструкции семантически идентичны:
a LEFT JOIN b USING (cl,c2,c3)
a LEFT JOIN b ON a.cl=b.cl AND a.c2=b.c2 AND a.c3=b.c3

  1. NATURAL [LEFT] JOIN для двух таблиц определено как семантический эквивалент INNER JOIN или LEFT join с конструкцией using, которая перечисляет все столбцы, присутствующие в обеих таблицах.
  2. INNER JOIN и , (запятая) семантически эквивалентны при отсутствии условия соединения: оба выполняют декартово произведение указанных таблиц (то есть каждая строка первой таблицы соединяется со всеми строками второй таблицы).
  3. RIGHT JOIN работает аналогично LEFT JOIN. Чтобы сохранять код переносимым между системами управления базами данных, рекомендуется использовать LEFT JOIN вместо RIGHT JOIN.
  4. STRAIGHT_JOIN идентично JOIN за исключением того, что левая таблица всегда читается раньше, чем правая. Это можно использовать в тех (немногих) случаях, когда оптимизатор располагает таблицы в неправильном порядке.

Начиная с MySQL 3.23.12, вы можете указывать подсказки (hints) о том, как MySQL должен использовать индексы при извлечении данных из таблицы. Указав USE index (список_ключей), вы можете принудить MySQL использовать только один из всех ин­дексов, чтобы искать строки в таблице. Альтернативный синтаксис IGNORE INDEX {спи-сок_ключей) может применяться, чтобы запретить MySQL использовать какой-то от­дельный индекс.
Эти подсказки удобны, если EXPLAIN показывает, что MySQL использует неправиль­ные индексы из списка возможных.
Начиная с MySQL 4.0.9, вы также можете использовать FORCE INDEX. Это работает подобно USE INDEX { список__ключей), но с тем отличием, что сканирование таблиц рас­ценивается, как очень дорогая операция. Другими словами, сканирование таблицы до­пускается только в том случае, если нет способа использования индекса для поиска строк в таблице.
USE KEY, IGNORE KEY И FORCE KEY - СИНОНИМЫ ДЛЯ USE INDEX, IGNORE INDEX И FORCE INDEX.

На заметку!
USE INDEX, IGNORE INDEX и FORCE INDEX влияют только на то, какие индексы будут исполь­зоваться, когда MySQL принимает решение о том, как искать строки в таблице и как выполнять соединение. Они не влияют на то, как будет использоваться индекс при вычислении ORDER BY
или GROUP BY.
Ниже представлены примеры соединений:
mysql> SELECT * FROM tablel,table2 WHERE tablel.id=table2.id; mysql> SELECT * FROM tablel LEFT JOIN table2 ON tableI.id=table2.id; mysql> SELECT * FROM tablel LEFT JOIN table2 USING (id); mysql> SELECT * FROM tablel LEFT JOIN table2 ON tablel.id=table2.id
-> LEFT JOIN table3 ON table2.id=table3.id;
mysql> SELECT * FROM tablel USE INDEX (keyl,key2)
-> WHERE key1=1 AND key2=2 AND key3=3;
mysql> SELECT * FROM tablel IGNORE INDEX (key3)
-> WHERE keyl=l AND key2=2 AND key3=3;
Синтаксис UNION
SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
UNION применяется для комбинирования результатов множества операторов SELECT в один результирующий набор. Оператор UNION доступен, начиная с MySQL 4.O.O.
Выбранные столбцы, перечисленные в соответствующих позициях каждого операто­ра SELECT, должны иметь одинаковый тип (например, первый столбец, выбираемый пер­вым оператором, должен иметь тот же тип, что и первый столбец, выбранный другими операторами). Имена столбцов первого оператора SELECT используются как имена столбцов для всех возвращаемых результатов.
Операторы SELECT — это обычные операторы извлечения строк, но со следующими ограничениями:

  1. Только один из операторов SELECT может иметь INTO OUTFILE.
  2. HIGH_PRIORITY не может использоваться с операторами SELECT, которые входят в UNION. Если вы указываете его в первом операторе SELECT, это не даст никакого эффекта. Если указать его в последующих операторах SELECT, результатом будет сообщение о синтаксической ошибке.

Если вы не используете ключевое слово ALL в UNION, все возвращенные строки будут уникальными, как если бы был указан DISTINCT для общего результирующего набора. Если ALL будет указан, вы получите все соответствующие строки от всех входящих в UNION операторов SELECT.
Ключевое слово DISTINCT является необязательным (оно введено в версии MySQL 4.0.17). Оно не делает ничего, но добавлено для обеспечения соответствия синтаксиса стандарту SQL.
На заметку!
Нельзя смешивать UNION ALL и UNION DISTINCT в одном запросе. Если указано ALL для одно­го UNION, оно применяется ко всем.

Если вы хотите применить ORDER BY для сортировки результата UNION, необходимо использовать скобки:
(SELECT a FROM имя_таблицыWHERE a=10 AND B=l ORDER BY a LIMIT 10)
UNION
(SELECT a FROM имя_таблицыWHERE a=ll AND B=2 ORDER BY a LIMIT 10)
ORDER BY a;
Типы и длина столбцов в результирующем наборе UNION принимают во внимание значения, извлеченные всеми операторами SELECT. До MySQL 4.1.1 существовало огра­ничение, заключающееся в том, что значения первого SELECT использовались для опре­деления типов и длин результирующих столбцов. Это могло приводить к усечению значений, если, например, первый SELECT извлекал значения, более короткие, чем второй:
mysql> SELECT REPEAT('a1,1) UNION SELECT REPEAT('Ь\ 10);