Сперва вас напугаем самой структурой оператора SELECT в СУБД MySQL.Выглядит она вот так:
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 ...]
[FROM table_references
[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 OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
Ну что, теперь приложим усилия чтоб это все разобрать и разложить по полкам.
[ALL | DISTINCT | DISTINCTROW ]
Используется чтоб убрать дубликаты. ALL установлено по умолчанию, поэтому его можно не писать. DISTINCTROW и DISTINCT
одинаковы: select distinct name from adm_user;
[HIGH_PRIORITY]
Данный параметр устанавливает высокий приоритет в очереди запросов и выполняется с приоритетом выше чем команды обновления таблицы. Параметр не желателен, но если уж вы его используете, запросы должны выполняться очень быстро и немедленно.
[STRAIGHT_JOIN]
Позволяет увеличить скорость, если вы уверены что оптимизатор запросов производит объединение таблиц не оптимальным образом. Оптимизатор объединит таблицы в порядке перечисленном в выражении FROM.
[SQL_SMALL_RESULT]
Может ускорить выполнение запросов при совместном использовании с GROUP BY или DISTINCT. Данный параметр рекомендуется использовать только при небольшом наборе данных. MySQL использует быстрые временные таблицы для хранения результирующей таблицы вместо сортировки.
[SQL_BIG_RESULT]
Можно использовать с GROUP BY или DISTINCT. Сообщает оптимизатору что результат будет содержать большое количество строк. При необходимости MySQL будет использовать временные таблицы на диске, но предпочтения будут у сортировки а не созданию временной таблицы с ключом по элементам GROUP BY.
[SQL_BUFFER_RESULT]
Результат заносит во временную таблицу перед тем как начать их передачу клиенту. Таким образом MySQL может раньше снять блокировку с таблицы.
[SQL_CACHE | SQL_NO_CACHE]
Очень полезный параметр который позволяет хранить результаты в кэше запросов при использовании QUERY_CACHE_TYPE=2. При повторном выполнении одного и того же запроса (текст запроса одинаков), результат будет мгновенный из кэша.
Соответственно SQL_NO_CACHE
- запрещает хранение в кэше.
[SQL_CALC_FOUND_ROWS]
Сразу скажу, параметр имеет смысл использовать вместе с параметром LIMIT. Указывая этот параметр MySQL подсчитает полное число строк, подходящих под условие запроса, и сохранит это значение в памяти. Получить это значение можно запросом: SELECT FOUND_ROWS();
select_expr [, select_expr ...]
Задает перечень полей которые необходимо вернуть результате.
Пример: SELECT 1 + 1, a.id, a.name FROM table a
table_references
В данном случае перечисляются таблицы из которых выбирается результат. Если их более одной, не забывайте объединять их. Как их правильно объединить я вам представлю в картинке на множестве, по мне это самый наглядный способ:
При необходимости также можно задавать какие индексы использовать а какие нет.
Пример представление одной таблицы:
your_name_table [[AS] alias]
your_name_table [[AS] alias]
[[USE INDEX (key_collection1)] |
[IGNORE INDEX (key_collection2)] |
FORCE INDEX (key_collection3)]]
, где
FORCE - использовать индекс всегда,
USE - если посчитает нужным оптимизатор MySQL,
IGNORE - игнорировать.
[WHERE where_condition]
Ключевое слово where говорит что далее пойдут условия отбора результата. Например выбрать всех у кого идентификатор более 10 и имя начинается с буквы "А" : SELECT * FROM table a where a.id > 10 and a.name like 'А%'
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
Этот оператор относится к группировки результатов. С данным оператором можно использовать только определенные функции (см.ниже). Например, подсчитаем какое количество людей имеют совпадения по имени. SELECT name, COUNT(id) FROM adm_user GROUP BY name;
Список групповых функций:
COUNT - количество величин со значением, не равным NULL
если добавить DISTINCT то будет количество различающихся величин со значением, не равным NULL.
SELECT name, COUNT(DISTINCT id) FROM adm_user GROUP BY name;
AVG(field) - среднее значение поля field,
MIN(field), MAX(field) - минимальное и максимальное значение поля.
SUM(field) - сумма величин поля field. Тут нужно быть внимательным, если возвращаемый набор данных пуст, то и функция вернет NULL!
STD(field) - среднеквадратичное отклонение значения в поля field.
BIT_OR(field) - побитовое ИЛИ для всех битов в field
BIT_AND(field) - побитовое И для всех битов в field.
Так же можно использовать [ASC | DESC], ... [WITH ROLLUP]. Это для того, чтоб выполнить групповую функция по каждой из групп но вместо себя будет подставлять NULL.
SELECT date_create, order_id, SUM(sum_price)
FROM sales
GROUP BY date_create, order_id WITH ROLLUP;
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
Limit или другими словами - постраничная навигация. Это означает что пользуясь данной конструкцией вы можете управлять количеством возвращаемых строк и границей отсчета этого результата. Пример, выбрать из таблицы третью четверку человек:
SELECT * FROM adm_user LIMIT 8, 4; # возвращает строки 9-12
также прошу заметить что offset не есть обязательным, если напишем так:
SELECT * FROM adm_user LIMIT 10;То это будет означать следующее: выбрать первые 10 человек.
[PROCEDURE procedure_name(argument_list)]
Даже не знаю пользуются ли этим, мне никогда не приходилось применять. Но все таки это есть и можно использовать. В MySQL есть возможность расширить определить процедуру написанную на C++, которая может обрабатывать в том числе и изменять данные до того как они будут переданы клиенту. Реализовать их очень просто - обратиться к специалисту, изложить суть, заплатить и получить желаемое.
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
Используется для экспорта возвращаемых строк в файл на диске или присвоении их в переменные. Да и есть отличия OUTFILE от DUMPFILE тем, что DUMPFILE применяется для экспорта полей BLOB, фалов или каких либо бинарников. DUMPFILE не добавляет симфолы форматирования а сохраняет так как есть.
Пример:
Экспорт в файл:
select * from adm_users into outfile 'c:\\table_adm_users.csv';
Присвоение значения в переменную:
select id, name into @prm_id, @prm_name from adm_users;
[FOR UPDATE | LOCK IN SHARE MODE]
Данные флаги используются для блокировки выбираемых данных для использования согласованного чтения. К примеру, вы желаете добавить сотрудника в отдел продаж, но в этот момент этот отдел удалили, вот тут для избежания ошибки можно воспользоваться LOCK IN SHARE MODE что заблокирует отдел пока вы в него не добавите сотрудника.
SELECT * FROM depts d WHERE d = 'отдел продаж' LOCK IN SHARE MODE;
UPDATE adm_users SET adm_users.depts_id = 4 WHERE adm_users.id = 2015;
Многие разработчики создают отдельную таблицу для хранения своих генераторов, так вот в этом случае можно воспользоваться FOR UPDATE.Сперва считаем текущее значение генератора:
SELECT value FROM sys_generator WHERE name = 'system_generator' FOR UPDATE
А теперь обновим его прибавив единицу:
UPDATE sys_generator SET value = value + 1 WHERE name = 'system_generator'
Таким образом у нас не будет конфликтных ситуаций по генерации ключей.
Не хватает информации, опишите в комментарии, какой и я обязательно ее добавлю. Всем спасибо!