какая конструкция команды select c name from cities c выполняется первой
Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite
Базы данных
SQL оператор SELECT
В этом учебном материале по SQL вы узнаете, как использовать оператор SELECT с синтаксисом и примерами.
Описание
SQL оператор SELECT используется для извлечения записей из одной или нескольких таблиц или представлений в базе данных SQL. Полученные записи известны как набор результатов.
Синтаксис
Синтаксис для оператора SELECT в SQL.
Параметры или аргумент
Давайте рассмотрим пример, который показывает, как использовать SQL запрос SELECT для выбора всех полей в таблице.
В этом примере у нас есть таблица customers со следующими данными:
customer_id | first_name | last_name | favorite_website |
---|---|---|---|
4000 | Justin | Bieber | google.com |
5000 | Selena | Gomez | bing.com |
6000 | Mila | Kunis | yahoo.com |
7000 | Tom | Cruise | oracle.com |
8000 | Johnny | Depp | NULL |
9000 | Russell | Crowe | google.com |
Будет выбрано 2 записи. Вот результаты, которые вы должны получить.
customer_id | first_name | last_name | favorite_website |
---|---|---|---|
4000 | Justin | Bieber | google.com |
9000 | Russell | Crowe | google.com |
Вы также можете использовать SQL оператор SELECT для выбора отдельных полей в таблице, в отличие от всех полей в таблице.
В этом примере у нас есть таблица suppliers со следующими данными:
supplier_id | supplier_name | city | state |
---|---|---|---|
100 | Yandex | Moscow | Russian |
200 | Lansing | Michigan | |
300 | Oracle | Redwood City | California |
400 | Bing | Redmond | Washington |
500 | Yahoo | Sunnyvale | Washington |
600 | DuckDuckGo | Paoli | Pennsylvania |
700 | Qwant | Paris | France |
800 | Menlo Park | California | |
900 | Electronic Arts | San Francisco | California |
Теперь давайте продемонстрируем, как использовать оператор SELECT для выбора отдельных столбцов таблицы. Введите следующую запроc SELECT.
SQL SELECT
Команда SELECT
Команда SELECT производит выборку данных из таблиц по запросу.
Язык SQL допускает три типа синтаксических конструкций, начинающихся с ключевого слова SELECT:
Синтаксис команды SELECT в MySQL
Синтаксис команды SELECT в Oracle
Основные ключевые слова и параметры команды SELECT в MySQL
Синтаксис команды SELECT в Oracle
Синтаксис команды SELECT в Oracle
Query table expression clause
Table collection expression
Hierarchical query clause
Основные ключевые слова и параметры команды SELECT в Oracle
Описание команды SELECT
Основой всех синтаксических конструкций, начинающихся с ключевого слова SELECT, является синтаксическая конструкция “табличное выражение”.
Семантика табличного выражения состоит в том, что на основе последовательного применения разделов FROM, WHERE, GROUP BY и HAVING из заданных в разделе FROM таблиц строится некоторая новая результирующая таблица, порядок следования строк которой не определен и среди строк которой могут находиться дубликаты (т.е. в общем случае таблица-результат табличного выражения является мультимножеством строк).
Наиболее общей является конструкция “спецификация курсора”. Курсор — это понятие языка SQL, позволяющее с помощью набора специальных операторов получить построчный доступ к результату запроса к БД. К табличным выражениям, участвующим в спецификации курсора, не предъявляются какие- либо ограничения. При определении спецификации курсора используются три дополнительных конструкции: спецификация запроса, выражение запросов и раздел ORDER BY.
В спецификации запроса задается список выборки (список арифметических выражений над значениями столбцов результата табличного выражения и констант). В результате применения списка выборки к результату табличного выражения производится построение новой таблицы, содержащей то же число строк, но вообще говоря другое число столбцов, содержащих результаты вычисления соответствующих арифметических выражений из списка выборки.
Выражение запросов — это выражение, строящееся по указанным синтаксическим правилам на основе спецификаций запросов. Единственной операцией, которую разрешается использовать в выражениях запросов, является операция UNION (объединение таблиц) с возможной разновидностью UNION ALL.
Оператор выборки — это отдельный оператор языка SQL, позволяющий получить результат запроса в прикладной программе без привлечения курсора. Поэтому оператор выборки имеет синтаксис, отличающийся от синтаксиса спецификации курсора, и при его выполнении возникают ограничения на результат табличного выражения. Фактически, и то, и другое диктуется спецификой оператора выборки как одиночного оператора SQL: при его выполнении результат должен быть помещен в переменные прикладной программы. Поэтому в операторе появляется раздел INTO, содержащий список переменных прикладной программы, и возникает то ограничение, что результирующая таблица должна содержать не более одной строки.
В диалекте SQL СУБД Oracle поддерживается расширенный вариант оператора выборки, результатом которого не обязательно является таблица из одной строки. Такое расширение не поддерживается ни в SQL/89, ни в SQL/92.
Подзапрос — запрос, который может входить в предикат условия выборки оператора SQL.
Кстати, данную статью Вы можете найти в интернете по запросам:
Команда SELECT, Синтаксис команды SELECT, Описание команды SELECT.
Порядок выполнения SQL-операций
Перевод статьи «SQL Order of Operations».
Мы привыкли, что компьютер выполняет команды программиста последовательно, в том порядке, который указал автор кода. Однако SQL относится к декларативным языкам, то есть SQL-запрос описывает ожидаемый результат, а не способ его получения.
Давайте разберём, в какой последовательности выполняются шесть операций в SQL: SELECT, FROM, WHERE, GROUP BY, HAVING и ORDER BY.
База данных выполняет команды в строгой очерёдности, о которой полезно знать любому разработчику. Залог оптимального запроса тот же, что и залог успеха в приготовлении вкусного блюда: важно знать не только ингредиенты, но и когда каждый из них должен попасть в блюдо. Если база данных отойдет от стандартного сценария выполнения команд, то ее производительность может сильно пострадать.
База данных сотрудников
В этой статье мы поработаем с типичной базой сотрудников, относящихся к разным отделам. По каждому сотруднику известны его ID, имя, фамилия, зарплата и отдел:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING |
101 | Mary | Sexton | 82,000 | IT |
102 | Chun | Yen | 80,500 | ACCOUNTING |
103 | Agnes | Miller | 95,000 | IT |
104 | Dmitry | Komer | 120,000 | SALES |
EMPLOYEE
DEPT_NAME | MANAGER | BUDGET |
---|---|---|
ACCOUNTING | 100 | 300,000 |
IT | 101 | 250,000 |
SALES | 104 | 700,000 |
DEPARTMENT
Проанализировать порядок выполнения команд в запросах помогут типичные задачи:
Начнем с получения имён сотрудников отдела IT:
В первую очередь выполняется FROM EMPLOYEE:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING |
101 | Mary | Sexton | 82,000 | IT |
102 | Chun | Yen | 80,500 | ACCOUNTING |
103 | Agnes | Miller | 95,000 | IT |
104 | Dmitry | Komer | 120,000 | SALES |
Затем наступает очередь WHERE DEPARTMENT = ‘IT’, который фильтрует колонку DEPARTMENT:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
101 | Mary | Sexton | 82,000 | IT |
103 | Agnes | Miller | 95,000 | IT |
Наконец, SELECT FIRST_NAME, LAST_NAME скрывает ненужные колонки и возвращает финальный результат:
FIRST_NAME | LAST_NAME |
---|---|
Mary | Sexton |
Agnes | Miller |
Отлично! После первого препарирования выяснилось, что простой запрос с операторами SELECT, FROM, и WHERE выполняется по следующей схеме:
Влияние ORDER BY на план выполнения запроса
Допустим, что начальнику не понравился отчет, основанный на предыдущем запросе, потому что он хочет видеть имена в алфавитном порядке. Исправим это с помощью ORDER BY:
Выполняться такой запрос будет так же, как и предыдущий. Только в конце ORDER BY отсортирует строки в алфавитном порядке по колонке FIRST_NAME:
FIRST_NAME | LAST_NAME |
---|---|
Agnes | Miller |
Mary | Sexton |
Таким образом, команды SELECT, FROM, WHERE и ORDER BY выполняются в следующей последовательности:
GROUP BY и HAVING
Усложним задачу. Посчитаем количество сотрудников каждого отдела с зарплатой выше 80 000 и остортируем результат по убыванию. Нам подойдёт следующий запрос:
Как обычно, в первую очередь выполнится FROM EMPLOYEE и вернет сырые данные:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING |
101 | Mary | Sexton | 82,000 | IT |
102 | Chun | Yen | 80,500 | ACCOUNTING |
103 | Agnes | Miller | 95,000 | IT |
104 | Dmitry | Komer | 120,000 | SALES |
После выполнения WHERE SALARY > 80000 выборка сузится:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
101 | Mary | Sexton | 82,000 | IT |
102 | Chun | Yen | 80,500 | ACCOUNTING |
103 | Agnes | Miller | 95,000 | IT |
104 | Dmitry | Komer | 120,000 | SALES |
Затем применяется GROUP BY. При этом генерируется по одной записи для каждого отдельного значения в указанной колонке. В нашем примере мы создаем по одной записи для каждого отдельного значения колонки DEPARTMENT:
DEPARTMENT |
---|
ACCOUNTING |
IT |
SALES |
После этого применяется SELECT с COUNT(*), производя промежуточный результат:
DEPARTMENT | COUNT(*) |
---|---|
ACCOUNTING | 1 |
IT | 2 |
SALES | 1 |
Применение ORDER BY завершает выполнение запроса и возвращает конечный результат:
DEPARTMENT | COUNT(*) |
---|---|
IT | 2 |
ACCOUNTING | 1 |
SALES | 1 |
План выполнения данного запроса следующий:
Добавим выражение HAVING
HAVING — это аналог WHERE для GROUP BY. С его помощью можно фильтровать агрегированные данные.
Давайте применим HAVING и определим, в каких отделах (за исключением отдела продаж) средняя зарплата сотрудников больше 80 000.
По уже известной нам схеме сначала выберем все данные из таблицы при помощи FROM EMPLOYEE:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING |
101 | Mary | Sexton | 82,000 | IT |
102 | Chun | Yen | 80,500 | ACCOUNTING |
103 | Agnes | Miller | 95,000 | IT |
104 | Dmitry | Komer | 120,000 | SALES |
Затем конструкция WHERE избавит нас от данных по отделу SALES:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING |
101 | Mary | Sexton | 82,000 | IT |
102 | Chun | Yen | 80,500 | ACCOUNTING |
103 | Agnes | Miller | 95,000 | IT |
GROUP BY сгенерирует следующие записи:
DEPARTMENT | AVG(SALARY) |
---|---|
ACCOUNTING | 79,250 |
IT | 88,500 |
HAVING AVG(SALARY) > 80000 ограничит список:
DEPARTMENT | AVG(SALARY) |
---|---|
IT | 88,500 |
А SELECT вернет финальный результат:
Порядок выполнения для данного запроса следующий:
Новый оператор — JOIN
До этого момента мы имели дело с одной таблицей. А что если воспользоваться JOIN и добавить ещё одну? Выясним фамилии и ID сотрудников, работающих в отделе с бюджетом более 275 000:
FROM EMPLOYEE как обычно запрашивает данные из таблицы EMPLOYEES:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT |
---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING |
101 | Mary | Sexton | 82,000 | IT |
102 | Chun | Yen | 80,500 | ACCOUNTING |
103 | Agnes | Miller | 95,000 | IT |
104 | Dmitry | Komer | 120,000 | SALES |
А теперь JOIN запросит сырые данные из DEPARTMENT и скомбинирует данные двух таблиц по условию ON DEPARTMENT = DEPT_NAME:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT | DEPT_NAME | MANAGER | BUDGET |
---|---|---|---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING | ACCOUNTING | 100 | 300,000 |
101 | Mary | Sexton | 82,000 | IT | IT | 101 | 250,000 |
102 | Chun | Yen | 80,500 | ACCOUNTING | ACCOUNTING | 100 | 300,000 |
103 | Agnes | Miller | 95,000 | IT | IT | 101 | 250,000 |
104 | Dmitry | Komer | 120,000 | SALES | SALES | 104 | 700,000 |
Потом применяем WHERE BUDGET > 275000:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY | DEPARTMENT | DEPT_NAME | MANAGER | BUDGET |
---|---|---|---|---|---|---|---|
100 | James | Smith | 78,000 | ACCOUNTING | ACCOUNTING | 100 | 300,000 |
102 | Chun | Yen | 80,500 | ACCOUNTING | ACCOUNTING | 100 | 300,000 |
104 | Dmitry | Komer | 120,000 | SALES | SALES | 104 | 700,000 |
SELECT EMPLOYEE_ID, LAST_NAME покажет финальный результат:
EMPLOYEE_ID | LAST_NAME |
---|---|
100 | Smith |
102 | Yen |
104 | Komer |
Для этого запроса план выполнения следующий:
Примеры разных запросов убедительно продемонстрировали, что существует строгий порядок выполнения операций. Но этот порядок может меняться в зависимости от набора команд в запросе. Вот универсальная шпаргалка по очередности выполнения операций в SQL-запросах:
Помните, что если исключить из этого списка один из операторов, то план выполнения может измениться.
Примеры использования инструкции SELECT (Transact-SQL)
В этом разделе приведены примеры применения инструкции SELECT.
A. Использование SELECT для получения строк и столбцов
В следующем примере приведены три примера кода. В ходе выполнения первого примера кода возвращаются все строки (предложение WHERE не указано), а также все столбцы (используется звездочка, * ) таблицы Product базы данных AdventureWorks2012.
Б. Использование SELECT с заголовками столбцов и вычислениями
Данный запрос вычисляет доход от продажи по каждому виду продукции для каждого заказа.
В. Совместное использование DISTINCT и SELECT
Г. Создание таблиц с помощью SELECT INTO
Д. Использование связанных вложенных запросов
Коррелированный запрос — это запрос, зависящий от результатов выполнения другого запроса. Он может повторно выполняться для каждой строки, выбранной с помощью другого запроса.
Коррелированный вложенный запрос также может использоваться в предложении HAVING внешнего запроса. В данном примере осуществляется поиск моделей продуктов, для которых максимальная цена в каталоге в два раза превышает среднюю цену по нему.
В данном примере с помощью двух коррелированных запросов осуществляется поиск сотрудников, продавших определенную продукцию.
Е. Использование GROUP BY
В следующем примере находится общий объем продаж для каждого заказа в базе данных.
Ж. Использование GROUP BY с несколькими группами
В данном примере вычисляются средние цены и объемы продаж за последний год, сгруппированные по коду продукта и идентификатору специального предложения.
З. Использование GROUP BY и WHERE
И. Использование GROUP BY с выражением
В следующем примере производится группировка с помощью выражения. Группировку можно производить только с помощью выражения, не содержащего агрегатных функций.
К. Использование GROUP BY с ORDER BY
В следующем примере для каждого типа продуктов вычисляется средняя цена, а также осуществляется сортировка полученных результатов по возрастанию.
Л. Использование предложения HAVING
В первом из приведенных ниже примеров показывается использование предложения HAVING с агрегатной функцией. В нем производится группировка строк таблицы SalesOrderDetail по коду продукта, а также удаляются строки, соответствующие продуктам, для которых средний объем заказа не превышает пяти. Во втором примере показывается использование предложения HAVING без агрегатной функции.
М. Использование HAVING с GROUP BY
Н. Использование HAVING с SUM и AVG
О. Использование указания оптимизатора INDEX
Н. Использование указаний OPTION и GROUP
П. Использование указания запроса UNION
Т. Использование простого UNION
У. Использование SELECT INTO с UNION
Ф. Использование UNION двух инструкций SELECT с ORDER BY
Х. Использование UNION трех инструкций SELECT для демонстрации эффекта от использования скобок и ALL
Открытый вебинар «Порядок выполнения запроса SELECT и план запроса в MS SQL Server»
Коллеги, в последний день января мы запускаем курс «MS SQL Server разработчик», в связи с чем у нас прошёл тематический открытый урок. На нём мы поговорили о том, как MS SQL Server выполняет запрос SELECT, обсудили, в каком порядке и что анализируется, а также немного погрузились в чтение плана запроса.
Преподаватель — Кристина Кучерова, архитектор модели данных в Сбербанке России.
Цели и маршрут вебинара
В начале вебинара были поставлены следующие цели:
Зачем нужен план запроса?
План запроса — очень полезный инструмент, который, к сожалению, многие разработчики не используют. На первый взгляд, может показаться, что совсем не обязательно знать механику запроса. Однако если вы будете понимать, что происходит внутри SQL Server, вы сможете написать более эффективный запрос. И это очень поможет, например, при оптимизации.
Как мы видим запрос SELECT?
Давайте посмотрим, как выглядит запрос SELECT:
SELECT [поле1], [поле2]… | Какие поля выбираем? |
FROM [таблица] | Откуда? |
WHERE [условия] | Где условия такие-то |
GROUP BY [поле1] | Сгруппируй по полям |
HAVING [условия] | Имеющим такие-то условия |
ORDER BY [поле1] | Упорядочи (отсортируй) |
Как понять, куда идти за данными?
Первое, что пытается понять сервер при поступлении запроса — куда идти за данными. На этот вопрос отвечает команда FROM, т. к. именно здесь у нас будет список таблиц (либо имя одной таблицы).
Для наглядности давайте представим, что наш сервер — это некий дворецкий, которому мы приказываем собрать нас в отпуск. Соответственно, дворецкий начинает думать, а в каком же шкафу лежат нужные вещи (в какой таблице нужно брать данные)? И чтобы наш дворецкий без затруднений выполнил свою задачу, мы используем FROM.
Как понять, какие данные брать?
Допустим, дворецкий нашёл нужный шкаф и открыл его. Но какие вещи брать? Может, мы едем на горнолыжный курорт? А может, на жаркий солнечный пляж? Чтобы наши вещи соответствовали погоде, нам пригодится команда WHERE, определяющая условия, то есть позволяющая отфильтровать данные. Если жарко, берём сланцы, майки и купальники, если холодно — варежки, вязаные носки, свитера)).
Следующий этап — вложить эти данные в группы, что происходит с помощью GROUP BY (майки отдельно, носки отдельно). По результатам группировки можно наложить ещё одно условие, используя HAVING (например, отсеиваем непарные вещи). В конечном итоге всё складываем с помощью ORDER BY, получая на выходе готовый чемодан вещей, а точнее — упорядоченный блок данных.
Кстати, тут есть нюанс, а заключается он в том, что есть разница, какие условия следует прописывать в WHERE, а какие в HAVING. Но об этом лучше посмотреть в видео.
Продолжаем. Путь выполнения запроса сохраняется в виде плана запроса в кэше, то бишь наш дворецкий всё записывает, ведь он хороший дворецкий — вдруг в следующем году вы захотите повторить свой приказ? И таких планов, в принципе, может быть много.
Виды соединений в плане запроса
Существуют три соединения, которые вы можете встретить в плане запроса:
Допустим, нам нужно соединить данные из разных таблиц. Давайте представим эти таблицы в виде… небольшого количества конфет Skittles и полной упаковки M&M’s.
При соединении типа Nested Loop мы берём конфету Skittles, а потом достаём вслепую конфету из пакета M&M’s. Если нам не попадается конфета такого же цвета (это наше условие), мы достаём следующую, то есть происходит обычный перебор. В результате можно сказать, что соединение Nested Loop больше подходит для небольших объёмов данных. Очевидно, что если данных много, перебор — не самый оптимальный вариант.
Посмотрим, как это выглядит в SQL-панели:
Соединение используется для больших объёмов данных. Когда у вас Merge join, у вас обе таблицы имеют индекс, по которому их можно соединить. В случае с конфетами – это как будто они у нас заранее разложены по цветам.
Выглядит всё следующим образом:
Merge join хорош в следующих случаях:
Hash join используется при неотсортированных больших объёмах данных. Для соединения таблиц в данном случае нужно построить что-то, имитирующее индекс.
Пример соединения Hash join:
Для наглядности вспомним наши конфеты:
Применение Hash join предполагает 2 фазы действий:
Когда хорош Hash join:
Друзья, кроме вышесказанного, в открытый урок вошли и другие интересные моменты, с которыми лучше всего ознакомиться, посмотрев видео. Мы же предлагаем посетить День открытых дверей курса «MS SQL Server разработчик», где можно будет задать преподавателю все интересующие вопросы.
P. S. Преподаватель Кристина Кучерова выражает признательность Jes Schultz Borland за её презентацию с PASS Summitt Execution Plans: The Secret to Query Tuning Success, которая была использована при подготовке открытого урока.