Урок 3. Порядок AND и OR
При использовании в SELECT-запросах операторов OR и AND можно легко ошибиться в составлении логического выражения. И проблема таких ошибок в том, что запрос выполняется как будто ошибки нет, но данные выводятся неверные.
Если у вас мало опыта в написании таких SQL-запросов, то можно легко не заметить проблему. Давайте разберем несколько популярных ошибок.
Работать будем с таблицей team, которая содержит список разработчиков:
| id | first_name | last_name | language | level |
|---|---|---|---|---|
| 1 | Дмитрий | Васильев | python | junior |
| 2 | Валерий | Юрьев | php | middle |
| 3 | Андрей | Ушаков | python | senior |
| 4 | Петр | Кузуб | javascript | junior |
| 5 | Наталья | Кузнецова | python | middle |
| 6 | Руслан | Исаков | php | senior |
| 7 | Сергей | Медведев | php | junior |
| 8 | Алексей | Борисов | python | middle |
| 9 | Валерия | Маркова | javascipt | senior |
Каждый разработчик оценивается project-менеджером по двум критериям, после чего он отбирает программиста на тот или иной проект. Основные критерии — это уровень владения технологией: junior, middle или senior, и базовый язык программирования, на котором пишет разработчик.
Нам как менеджерам поступает заявка на разработку проекта и на основании этой заявки мы должны подобрать необходимых разработчиков.
Представьте, что сейчас нас интересуют только мидллы и сеньоры. Напишем SQL-запрос:
SELECT * FROM team WHERE level = 'middle' AND level = 'senior'
После выполнения запроса мы увидим пустую таблицу.
| id | first_name | last_name | language | level |
|---|
И тут мы столкнулись с первой ошибкой. В нашем запросе база данных по очереди берет строку и проверяет находится ли в колонке level значение «middle» И значение «senior». Оператор AND — это условие одновременности. То есть исходя из нашего запроса в поле level должно находится одновременно и «middle», и «senior», что невозможно, так разработчик может быть только одного уровня.
Почему мы допустили такую ошибку? И дело в формулировках, когда я озвучивал задание, то сказал, что нас интересуют только мидлы И сеньоры. Это правильное выражение с точки зрения русского языка, но неверное с точки зрения логики. Чтобы получить верный результат надо чтобы поле level содержало ИЛИ «middle», ИЛИ «senior». Поэтому заменим AND на OR:
SELECT * FROM team WHERE level = 'middle' OR level = 'senior'
Теперь разработчики подобраны верно:
| id | first_name | last_name | language | level |
|---|---|---|---|---|
| 2 | Валерий | Юрьев | php | middle |
| 3 | Андрей | Ушаков | python | senior |
| 5 | Наталья | Кузнецова | python | middle |
| 6 | Руслан | Исаков | php | senior |
| 8 | Алексей | Борисов | python | middle |
| 9 | Валерия | Маркова | javascipt | senior |
Такую ошибку легко допустить, если в формулировке задачи стоит союз И. Но не стоит его напрямую переносить в SQL-запрос. Возможно здесь кроется ошибка, особенно если мы сравниваем с одним полем.
Давайте рассмотрим другой случай. На этот раз нам нужно разработать бэкенд для сайта. И для этого нам нужны все Python и PHP разработчики. Напишем:
SELECT * FROM team WHERE basic_language = 'Python' OR basic_language = "PHP"
Обратите внимание, что нужны нам все Python И PHP разработчики, но пишем мы OR. После выполнения запроса мы получим такую таблицу:
| id | first_name | last_name | language | level |
|---|---|---|---|---|
| 1 | Дмитрий | Васильев | python | junior |
| 2 | Валерий | Юрьев | php | middle |
| 3 | Андрей | Ушаков | python | senior |
| 5 | Наталья | Кузнецова | python | middle |
| 6 | Руслан | Исаков | php | senior |
| 7 | Сергей | Медведев | php | junior |
| 8 | Алексей | Борисов | python | middle |
В итоговую таблицу попали и те и другие программисты. Отлично. Но давайте расширим условие. Скажем, нам нужны только middle разработчики на этих языках. Добавим:
SELECT * FROM team WHERE basic_language = 'Python' OR basic_language = "PHP" AND level = "middle"
После выполнения мы получим такую таблицу:
| id | first_name | last_name | language | level |
|---|---|---|---|---|
| 1 | Дмитрий | Васильев | python | junior |
| 2 | Валерий | Юрьев | php | middle |
| 3 | Андрей | Ушаков | python | senior |
| 5 | Наталья | Кузнецова | python | middle |
| 8 | Алексей | Борисов | python | middle |
И результат довольно странный, в итоговой таблице присутствуют также джуниоры и сеньоры. И дело в том, что операторы OR и AND имеют приоритет выполнения и у AND он выше. Поэтому в первую очередь база данных находит всех мидлов, которые пишут на PHP. Такому условию соответствует только одна запись, а далее срабатывает оператор OR, который добавляет всех Python-разработчиков.
То есть мы ищем ИЛИ мидлов на PHP, ИЛИ Python-разработчиков без указания их уровня владения языком. Поэтому в таблицу также попали джуниоры и сеньоры.
Чтобы решить поставленную задачу, нужно четко расставить приоритет с помощью скобок. Как в математике. Поместим скобки справа и слева от OR:
SELECT * FROM team WHERE (basic_language = 'Python' OR basic_language = "PHP") AND level = "middle"
Теперь в таблице остались только мидлы на Python и PHP:
| id | first_name | last_name | language | level |
|---|---|---|---|---|
| 2 | Валерий | Юрьев | php | middle |
| 5 | Наталья | Кузнецова | python | middle |
| 8 | Алексей | Борисов | python | middle |
Каждый раз когда в одном запросе встречаются OR и AND, обращайте внимание на порядок выполнения, иначе можно легко получить неверные данные.
Вообще, даже не так, каждый раз когда у вас есть в запросе есть OR и AND применяйте скобки для расстановки приоритетов, даже если уверены в своём коде.
Такая практика позволит избежать неприятных логических ошибок.
Следующий урок
Урок 4. Сортировка результатов
В этом уроке вы научитесь сортировать итоговые результаты в возрастающем и убывающем порядке с помощью ORDER BY.
Полный курс с практикой
- 57 уроков
- 261 задание
- Сертификат
- Поддержка преподавателя
- Доступ к курсу навсегда
- Можно в рассрочку
Руководство по созданию запроса Oracle из Кластера больших данных SQL Server
Поддержка надстройки «Кластеры больших данных» Microsoft SQL Server 2019 будет прекращена. Мы прекратим поддержку Кластеров больших данных SQL Server 2019 28 февраля 2025 г. Все существующие пользователи SQL Server 2019 с Software Assurance будут полностью поддерживаться на платформе, а программное обеспечение будет продолжать поддерживаться через SQL Server накопительных обновлений до этого времени. Дополнительные сведения см. в записи блога объявлений и в статье о параметрах больших данных на платформе Microsoft SQL Server.
В этом руководстве описывается, каким образом выполняется запрос данных Oracle из кластера больших данных SQL Server 2019. Для работы с этим руководством требуется доступ к серверу Oracle. Требуется учетная запись пользователя Oracle с правами на чтение для внешнего объекта. Поддерживается проверка подлинности пользователя через прокси-сервер Oracle. Если у вас нет доступа к серверу, из этого руководства вы можете узнать о принципах виртуализации данных для внешних источников в кластере больших данных SQL Server.
В этом руководстве описано следующее:
- Создание внешней таблицы для данных во внешней базе данных Oracle.
- Объединение этих данных с важными данными в главном экземпляре.
При необходимости вы можете скачать и выполнить скрипт, содержащий команды из этого руководства. См. инструкции в разделе Примеры виртуализации данных на сайте GitHub.
Предварительные требования
- Средства работы с большими данными
- kubectl
- Azure Data Studio
- Расширение SQL Server 2019
Создание таблицы Oracle
Далее описывается создание примера таблицы с именем INVENTORY в Oracle.
- Подключитесь к базе данных и экземпляру Oracle, которые вы хотите использовать для этого руководства.
- Чтобы создать эту таблицу INVENTORY , используйте следующую инструкцию:
CREATE TABLE "INVENTORY" ( "INV_DATE" NUMBER(10,0) NOT NULL, "INV_ITEM" NUMBER(10,0) NOT NULL, "INV_WAREHOUSE" NUMBER(10,0) NOT NULL, "INV_QUANTITY_ON_HAND" NUMBER(10,0) ); CREATE INDEX INV_ITEM ON HR.INVENTORY(INV_ITEM);Создание внешнего источника данных
Для начала необходимо создать внешний источник данных, который может обращаться к вашему серверу Oracle.
- В Azure Data Studio установите подключение к главному экземпляру SQL Server в кластере больших данных. Дополнительные сведения см. в разделе Подключение к главному экземпляру SQL Server.
- Дважды щелкните подключение в окне Серверы, чтобы открыть панель мониторинга сервера для главного экземпляра SQL Server. Выберите Создать запрос.
- Выполните следующую команду Transact-SQL, чтобы изменить контекст на базу данных Sales в главном экземпляре.
USE Sales GOCREATE DATABASE SCOPED CREDENTIAL [OracleCredential] WITH IDENTITY = '', SECRET = '';CREATE EXTERNAL DATA SOURCE [OracleSalesSrvr] WITH (LOCATION = 'oracle://',CREDENTIAL = [OracleCredential]);Необязательно. Проверка подлинности прокси-сервера Oracle
Oracle поддерживает проверку подлинности прокси-сервера для обеспечения точной детализации управления доступом. Пользователь прокси-сервера подключается к базе данных Oracle, используя ее учетные данные, и олицетворяет другого пользователя в базе данных.
Пользователя прокси-сервера можно настроить таким образом, чтобы он имел ограниченный доступ по сравнению с олицетворением пользователя. Например, пользователю прокси-сервера можно разрешить подключаться с помощью определенной роли базы данных олицетворенного пользователя. Удостоверение пользователя, подключающегося к базе данных Oracle через прокси-сервер, сохраняется в соединении, даже если с помощью проверки подлинности прокси-сервера подключаются несколько пользователей. Это позволяет Oracle принудительно применять управление доступом и выполнять аудит действий, выполняемых от имени фактического пользователя.
Если в сценарии требуется использование пользователя прокси-сервера Oracle, вместо шагов 4 и 5 сделайте следующие.
-
Создайте учетные данные в области базы данных для подключения к серверу Oracle. Предоставьте соответствующие учетные данные пользователя прокси-сервера Oracle для сервера Oracle в следующей инструкции.
CREATE DATABASE SCOPED CREDENTIAL [OracleProxyCredential] WITH IDENTITY = '', SECRET = '';CREATE EXTERNAL DATA SOURCE [OracleSalesSrvr] WITH (LOCATION = 'oracle://', CONNECTION_OPTIONS = 'ImpersonateUser=%CURRENT_USER', CREDENTIAL = [OracleProxyCredential]);Создание внешней таблицы
Далее создайте внешнюю таблицу с именем iventory_ora на основе таблицы INVENTORY на сервере Oracle.
CREATE EXTERNAL TABLE [inventory_ora] ([inv_date] DECIMAL(10,0) NOT NULL, [inv_item] DECIMAL(10,0) NOT NULL, [inv_warehouse] DECIMAL(10,0) NOT NULL, [inv_quantity_on_hand] DECIMAL(10,0)) WITH (DATA_SOURCE=[OracleSalesSrvr], LOCATION='..');При выполнении запросов к Oracle в именах таблиц и столбцов будет использоваться идентификатор SQL ANSI в кавычках. В связи с этим в таких именах учитывается регистр букв. В определении внешней таблицы важно указывать имена, которые в точности соответствуют именам таблиц и столбцов в метаданных Oracle.
Запрос данных
Выполните следующий запрос, чтобы объединить данные во внешней таблице iventory_ora с таблицами в локальной базе данных Sales .
SELECT TOP(100) w.w_warehouse_name, i.inv_item, SUM(i.inv_quantity_on_hand) as total_quantity FROM [inventory_ora] as i JOIN item as it ON it.i_item_sk = i.inv_item JOIN warehouse as w ON w.w_warehouse_sk = i.inv_warehouse WHERE it.i_category = 'Books' and i.inv_item BETWEEN 1 and 18000 --> get items within specific range GROUP BY w.w_warehouse_name, i.inv_item;Очистка
Выполните следующую команду, чтобы удалить объекты базы данных, созданные в рамках этого руководства.
DROP EXTERNAL TABLE [inventory_ora]; DROP EXTERNAL DATA SOURCE [OracleSalesSrvr] ; DROP DATABASE SCOPED CREDENTIAL [OracleCredential];Дальнейшие действия
Сведения о приеме данных в пул данных:
Язык SQL — Основы аналитики на SQL
В современном мире данные создаются с огромной скоростью. Мы постоянно делаем фотографии, снимаем видео, покупаем товары в интернет-магазинах, посещаем сайты, пишем посты в соцсетях. Все эти данные можно хранить на компьютерах, внешних носителях или в облачных сервисах. Но для организованного хранения больших объемов информации эти способы не подойдут.
В таких случаях лучшим вариантом будут базы данных. Они похожи на коробки — в них можно складывать информацию и хранить ее так, чтобы было легко найти.
Для работы с базами используются разные СУБД — системы управления базами данных. Это специальные программы, которые позволяют создавать, удалять, менять и читать информацию из базы.
Формат базы зависит от типа СУБД. Например, данные можно хранить в виде таблиц из строк и столбцов — таким образом устроены реляционные СУБД. Яркие примеры реляционных СУБД — это MySQL, PostgreSQL и Oracle.
Чтобы работать с реляционными СУБД, нужно освоить SQL — язык запросов к базам данных. В этом уроке мы начнем знакомиться с этим языком.
Как аналитики используют SQL
Чтобы обращаться к записям в базе данных, используется SQL — язык структурированных запросов. С его помощью можно легко и быстро получать нужные данные, добавлять новые записи, изменять или удалять существующие.
В SQL есть несколько основных типов команд:
- SELECT — выбрать данные из базы, то есть получить информацию, отфильтровать ее или отсортировать по критериям
- INSERT — добавить новые записи в базу данных
- UPDATE — изменить существующие данные в базе, то есть обновить значения в определенных строках и столбцах таблицы
- DELETE — удалить данные из базы
На практике аналитики данных чаще всего используют команду SELECT . Она помогает получать нужную информацию из базы данных, чтобы затем провести анализ и принять обоснованные решения.
Язык SQL в аналитике решает множество задач:
- Фильтрация данных — можно выбрать только те данные, которые соответствуют определенным условиям. Это очень полезно, когда аналитику нужно сосредоточиться на конкретных значениях или категориях
- Сортировка данных — можно отсортировать данные по возрастанию или убыванию и упорядочить их по определенным критериям. Это заметно облегчает анализ
- Вычисление агрегатных функций — можно воспользоваться встроенными функции и рассчитать сумму, среднее значение, минимальное и максимальное значение, а также другие статистические показатели. Это помогает аналитикам быстро оценить общую картину и определить тренды
- Объединение данных из разных таблиц — можно связывать данные из разных таблиц, чтобы получить более полную информацию для анализа. Это особенно полезно, когда данные хранятся в отдельных таблицах, но связаны между собой
- Группировка данных — можно сгруппировать данные по определенным критериям, чтобы увидеть общие закономерности и зависимости. Это упрощает анализ и помогает найти важные инсайты
На этом курсе мы научимся решать все эти задачи.
Как работать с SQLime
Для обучения аналитике на SQL мы будем пользоваться SQLime — удобным онлайн-инструментом, который не требует установки программы на компьютер. Это интерактивная среда, в которой можно писать и выполнять SQL-запросы.
Чтобы начать пользоваться SQLime, откройте сайт SQLime в браузере.
На главной странице вы увидите:
Страница состоит из двух блоков:
- Окно для ввода SQL-запросов. Здесь вы можете использовать подсказки и автодополнение кода, чтобы ускорить процесс написания запросов и уменьшить вероятность ошибок
- Окно для вывода результатов. Здесь вы увидите результаты выборки данных, обновлений, добавления или удаления записей
В SQLime можно подключиться к любой локальной или удаленной реляционной базе данных. Это можно сделать разными способами:
- С помощью файла в формате .db
- C помощью URL-ссылки
- С помощью команд CREATE и INSERT
Для примера возьмем уже созданную базу данных с информацией о продажах товаров в разных магазинах. Чтобы поработать с ней, достаточно перейти по ссылке .
Как извлекать записи
Выполним первый запрос:
SELECT * FROM products;Рассмотрим его подробнее:
- Ключевое слово SELECT указывает, что мы хотим извлечь данные из таблицы
- Символ * означает, что мы хотим выбрать все столбцы из таблицы
- Ключевое слово FROM указывает, из какой таблицы извлечь данные
- Название products обозначает таблицу, из которой мы хотим извлечь данные
Выполнив этот запрос, мы получим таблицу со всеми строками и столбцами из таблицы products :
Здесь мы видим полную информацию о каждом продукте, включая его идентификатор, название, категорию и цену.
Аналогично предыдущему примеру, можно извлечь все записи из sales — таблицы с продажами:
SELECT * FROM sales;Такой результат мы получим:
Если нужны какие-то конкретные поля, можно перечислить их через запятую вместо звездочки:
SELECT sale_id, sale_date, quantity FROM sales;Сделав такой запрос, мы получим таблицу с тремя столбцами:
Как работает пагинация
Пагинация позволяет разбить большой набор данных на меньшие части, которые можно отображать на разных страницах. В SQL для этого используются операторы LIMIT и OFFSET .
Допустим, мы хотим посмотреть список продаж на страницах, каждая из которых содержит по три записи. Чтобы получить продажи на первой странице, используем следующий SQL-запрос:
SELECT * FROM sales LIMIT 3 OFFSET 0;Результат этого запроса выглядит так:
Чтобы просмотреть продажи на второй странице, увеличим значение OFFSET на 3:
SELECT * FROM sales LIMIT 3 OFFSET 3;Получим такую таблицу:
Операторы LIMIT и OFFSET ограничивают количество возвращаемых строк и пропускают определенное количество строк перед началом извлечения:
- Оператор LIMIT определяет максимальное количество строк в результате. Например, LIMIT 3 ограничивает результат до трех строк
- OFFSET определяет, сколько строк следует пропустить перед извлечением. Например, запрос с OFFSET 3 пропустит первые три строки и вернет результаты, начиная с четвертой строки
Чтобы получить продажи на N-ной странице, обычно используют OFFSET с такой формулой:
OFFSET (N — 1) * количество_записей_на_странице`Для примера вычислим значение OFFSET , которое покажет продажи на третьей странице:
(3 — 1) * 3 = 6Как присвоить псевдоним
Чтобы работать с базой данных было удобнее, мы можем изменить названия на более понятные.
Для этого используется оператор AS , который присваивает строке, столбцу или таблице более удобное название — псевдоним (alias).
Попробуем присвоить псевдонимы столбцам product_name , category , и price :
SELECT product_id, product_name AS "Название продукта", category AS "Категория", price AS "Цена" FROM products;В выводе мы увидим таблицу с понятными названиями:
Как найти уникальные значения
Представим, нам нужно проанализировать ассортимент магазина и найти в нем уникальные категории товаров. Для таких задач используется оператор DISTINCT . Он позволяет получить уникальные значения определенного столбца или набора столбцов.
Извлечем уникальные категории из таблицы products .
SELECT DISTINCT category FROM products;В результате мы увидим три уникальные категории:
Если в таблице есть несколько товаров с одинаковыми категориями, то в результате запроса каждая категория появится только один раз.
Выводы
В этом уроке мы начали знакомиться с языком запросов SQL. Подведем краткие итоги:
- В современном мире очень много информации — такие объемы удобнее всего хранить в базах данных
- Базы данных управляются с помощью СУБД — систем управления базами данных. Они позволяют организовать хранение в различных форматах и структурах
- Реляционные СУБД работают с данными, которые хранятся в таблицах из строк и столбцов
- Язык SQL используется для обращения к данным, хранящимся в базе данных и управления ими
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
SQL запросы быстро. Часть 1
Язык SQL очень прочно влился в жизнь бизнес-аналитиков и требования к кандидатам благодаря простоте, удобству и распространенности. Из собственного опыта могу сказать, что наиболее часто SQL используется для формирования выгрузок, витрин (с последующим построением отчетов на основе этих витрин) и администрирования баз данных. И поскольку повседневная работа аналитика неизбежно связана с выгрузками данных и витринами, навык написания SQL запросов может стать фактором, из-за которого кандидат или получит преимущество, или будет отсеян. Печальная новость в том, что не каждый может рассчитывать получить его на студенческой скамье. Хорошая новость в том, что в изучении SQL нет ничего сложного, это быстро, а синтаксис запросов прост и понятен. Особенно это касается тех, кому уже доводилось сталкиваться с более сложными языками.
Обучение SQL запросам я разделил на три части. Эта часть посвящена базовому синтаксису, который используется в 80-90% случаев. Следующие две части будут посвящены подзапросам, Join’ам и специальным операторам. Цель гайдов: быстро и на практике отработать синтаксис SQL, чтобы добавить его к арсеналу навыков.
Практика
Введение в синтаксис будет рассмотрено на примере открытой базы данных, предназначенной специально для практики SQL. Чтобы твое обучение прошло максимально эффективно, открой ссылку ниже в новой вкладке и сразу запускай приведенные примеры, это позволит тебе лучше закрепить материал и самостоятельно поработать с синтаксисом.
Кликнуть здесь
После перехода по ссылке можно будет увидеть сам редактор запросов и вывод данных в центральной части экрана, список таблиц базы данных находится в правой части.
Структура sql-запросов
Общая структура запроса выглядит следующим образом:
SELECT ('столбцы или * для выбора всех столбцов; обязательно') FROM ('таблица; обязательно') WHERE ('условие/фильтрация, например, city = 'Moscow'; необязательно') GROUP BY ('столбец, по которому хотим сгруппировать данные; необязательно') HAVING ('условие/фильтрация на уровне сгруппированных данных; необязательно') ORDER BY ('столбец, по которому хотим отсортировать вывод; необязательно')Разберем структуру. Для удобства текущий изучаемый элемент в запроса выделяется CAPS’ом.
SELECT, FROM
SELECT, FROM — обязательные элементы запроса, которые определяют выбранные столбцы, их порядок и источник данных.
Выбрать все (обозначается как *) из таблицы Customers:
SELECT * FROM CustomersВыбрать столбцы CustomerID, CustomerName из таблицы Customers:
SELECT CustomerID, CustomerName FROM CustomersWHERE
WHERE — необязательный элемент запроса, который используется, когда нужно отфильтровать данные по нужному условию. Очень часто внутри элемента where используются IN / NOT IN для фильтрации столбца по нескольким значениям, AND / OR для фильтрации таблицы по нескольким столбцам.
Фильтрация по одному условию и одному значению:
select * from Customers WHERE City = 'London'Фильтрация по одному условию и нескольким значениям с применением IN (включение) или NOT IN (исключение):
select * from Customers where City IN ('London', 'Berlin')select * from Customers where City NOT IN ('Madrid', 'Berlin','Bern')Фильтрация по нескольким условиям с применением AND (выполняются все условия) или OR (выполняется хотя бы одно условие) и нескольким значениям:
select * from Customers where Country = 'Germany' AND City not in ('Berlin', 'Aachen') AND CustomerID > 15select * from Customers where City in ('London', 'Berlin') OR CustomerID > 4GROUP BY
GROUP BY — необязательный элемент запроса, с помощью которого можно задать агрегацию по нужному столбцу (например, если нужно узнать какое количество клиентов живет в каждом из городов).
При использовании GROUP BY обязательно:
- перечень столбцов, по которым делается разрез, был одинаковым внутри SELECT и внутри GROUP BY,
- агрегатные функции (SUM, AVG, COUNT, MAX, MIN) должны быть также указаны внутри SELECT с указанием столбца, к которому такая функция применяется.
select City, count(CustomerID) from Customers GROUP BY CityГруппировка количества клиентов по стране и городу:
select Country, City, count(CustomerID) from Customers GROUP BY Country, CityГруппировка продаж по ID товара с разными агрегатными функциями: количество заказов с данным товаром и количество проданных штук товара:
select ProductID, COUNT(OrderID), SUM(Quantity) from OrderDetails GROUP BY ProductIDГруппировка продаж с фильтрацией исходной таблицы. В данном случае на выходе будет таблица с количеством клиентов по городам Германии:
select City, count(CustomerID) from Customers WHERE Country = 'Germany' GROUP BY CityПереименование столбца с агрегацией с помощью оператора AS. По умолчанию название столбца с агрегацией равно примененной агрегатной функции, что далее может быть не очень удобно для восприятия.
select City, count(CustomerID) AS Number_of_clients from Customers group by CityHAVING
HAVING — необязательный элемент запроса, который отвечает за фильтрацию на уровне сгруппированных данных (по сути, WHERE, но только на уровень выше).
Фильтрация агрегированной таблицы с количеством клиентов по городам, в данном случае оставляем в выгрузке только те города, в которых не менее 5 клиентов:
select City, count(CustomerID) from Customers group by City HAVING count(CustomerID) >= 5В случае с переименованным столбцом внутри HAVING можно указать как и саму агрегирующую конструкцию count(CustomerID), так и новое название столбца number_of_clients:
select City, count(CustomerID) as number_of_clients from Customers group by City HAVING number_of_clients >= 5Пример запроса, содержащего WHERE и HAVING. В данном запросе сначала фильтруется исходная таблица по пользователям, рассчитывается количество клиентов по городам и остаются только те города, где количество клиентов не менее 5:
select City, count(CustomerID) as number_of_clients from Customers WHERE CustomerName not in ('Around the Horn','Drachenblut Delikatessend') group by City HAVING number_of_clients >= 5ORDER BY
ORDER BY — необязательный элемент запроса, который отвечает за сортировку таблицы.
Простой пример сортировки по одному столбцу. В данном запросе осуществляется сортировка по городу, который указал клиент:
select * from Customers ORDER BY CityОсуществлять сортировку можно и по нескольким столбцам, в этом случае сортировка происходит по порядку указанных столбцов:
select * from Customers ORDER BY Country, CityПо умолчанию сортировка происходит по возрастанию для чисел и в алфавитном порядке для текстовых значений. Если нужна обратная сортировка, то в конструкции ORDER BY после названия столбца надо добавить DESC:
select * from Customers order by CustomerID DESCОбратная сортировка по одному столбцу и сортировка по умолчанию по второму:
select * from Customers order by Country DESC, CityJOIN
JOIN — необязательный элемент, используется для объединения таблиц по ключу, который присутствует в обеих таблицах. Перед ключом ставится оператор ON.
Запрос, в котором соединяем таблицы Order и Customer по ключу CustomerID, при этом перед названиям столбца ключа добавляется название таблицы через точку:
select * from Orders JOIN Customers ON Orders.CustomerID = Customers.CustomerIDНередко может возникать ситуация, когда надо промэппить одну таблицу значениями из другой. В зависимости от задачи, могут использоваться разные типы присоединений. INNER JOIN — пересечение, RIGHT/LEFT JOIN для мэппинга одной таблицы знаениями из другой,
select * from Orders join Customers on Orders.CustomerID = Customers.CustomerID where Customers.CustomerID >10Внутри всего запроса JOIN встраивается после элемента from до элемента where, пример запроса:
Другие типы JOIN’ов можно увидеть на замечательной картинке ниже:

В следующей части подробнее поговорим о типах JOIN’ов и вложенных запросах.
При возникновении вопросов/пожеланий, всегда прошу обращаться!
