Евгений Колесников 1 gadu atpakaļ
vecāks
revīzija
9abb3edec2
2 mainītis faili ar 42 papildinājumiem un 160 dzēšanām
  1. 42 160
      articles/sql_for_beginner.md
  2. BIN
      img/sql014.png

+ 42 - 160
articles/sql_for_beginner.md

@@ -1,10 +1,6 @@
-<table style="width: 100%;"><tr><td style="width: 40%;">
-<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы
-</a></td><td style="width: 20%;">
-<a href="../readme.md">Содержание
-</a></td><td style="width: 40%;">
-<a href="../articles/sql_import.md">Создание базы данных. Импорт данных.
-</a></td><tr></table>
+Предыдущая лекция | &nbsp; | Следующая лекция
+:----------------:|:----------:|:----------------:
+[Словарь данных](./5_1_1_1_data_dictionary.md) | [Содержание](../readme.md#проектирование-баз-данных) | [Создание базы данных. Импорт данных.](./sql_import.md)
 
 # Основы SQL (синтаксис MySQL)
 
@@ -41,6 +37,14 @@
 
 * **Transaction Control Language (TCL)** – группа операторов для управления транзакциями. Транзакция – это команда или блок команд (инструкций), которые успешно завершаются как единое целое, при этом в базе данных все внесенные изменения фиксируются на постоянной основе или отменяются, т.е. все изменения, внесенные любой командой, входящей в транзакцию, будут отменены.
 
+## Ключевое слово USE
+
+В одной СУБД может быть создано несколько баз данных. При выполнении SQL команд мы можем либо указывать нужную БД в команде, либо предварительно указать какая база будет использоваться для комад
+
+```sql
+USE db_name;
+```
+
 ## Data Manipulation Language (DML)
 
 ### Базовый синтаксис SQL команды SELECT
@@ -50,7 +54,7 @@
 Общая структура запроса:
 
 ```sql
-SELECT [DISTINCT | ALL] поля_таблиц 
+SELECT [DISTINCT | ALL] поля_таблиц | функция | литерал
     [FROM список_таблиц] 
     [WHERE условия_на_ограничения_строк]
     [GROUP BY условия_группировки]
@@ -70,8 +74,8 @@ SELECT [DISTINCT | ALL] поля_таблиц
 * **GROUP BY** используется для группировки строк
 * **HAVING** применяется после группировки строк для фильтрации по значениям агрегатных функций
 * **ORDER BY** используется для сортировки. У него есть два параметра:
-* **ASC** (по умолчанию) используется для сортировки по возрастанию
-* **DESC** — по убыванию
+    * **ASC** (по умолчанию) используется для сортировки по возрастанию
+    * **DESC** — по убыванию
 * **LIMIT** используется для ограничения количества строк для вывода
 
 #### SQL-псевдонимы
@@ -80,7 +84,7 @@ SELECT [DISTINCT | ALL] поля_таблиц
 
 Например, если в вашей таблице есть столбец **goodTypeId**, вы можете переименовать его просто в **id**, для того, чтобы сделать его более коротким и удобным в использовании в будущем.
 
-Для создания псевдонимов используется оператор AS:
+Для создания псевдонимов используется оператор `AS`:
 
 ```sql
 SELECT 
@@ -153,8 +157,6 @@ SELECT поля_таблиц
         [логический_оператор другое_условия_на_ограничения_строк];
 ```
 
-В описанной структуре запроса необязательные параметры указаны в квадратных скобках.
-
 В условном операторе применяются операторы сравнения, специальные и логические операторы.
 
 #### Операторы сравнения
@@ -262,10 +264,10 @@ ESCAPE '!';
 
 Логические операторы необходимы для связывания нескольких условий ограничения строк.
 
-* Оператор NOT — меняет значение специального оператора на противоположный
-* Оператор OR — общее значение выражения истинно, если хотя бы одно из них истинно
-* Оператор AND — общее значение выражения истинно, если они оба истинны
-* Оператор XOR — общее значение выражения истинно, если один и только один аргумент является истинным
+* Оператор **NOT** — меняет значение специального оператора на противоположный
+* Оператор **OR** — общее значение выражения истинно, если хотя бы одно из них истинно
+* Оператор **AND** — общее значение выражения истинно, если они оба истинны
+* Оператор **XOR** — общее значение выражения истинно, если один и только один аргумент является истинным
 
 Выведем все полёты, которые были совершены на самолёте «Boeing», но, при этом, вылет был не из Лондона:
 
@@ -335,7 +337,7 @@ id | name  | phone
 1  | Иванов| 322223
 2  | Петров| 111111
 
->Сводные выборки нам понадобятся при импорте данных в базу. Сначала вы выделяете из таблиц импорта словари. А потом из таблиц импорта и словарей формируете запрос `INSERT ... SELECT` для записи данных в основную таблицу.
+>Сводные выборки нам понадобятся при импорте данных в базу.
 
 #### Вложенные SQL запросы
 
@@ -391,7 +393,7 @@ WHERE
     );
 ```
 
-С помощью данного запроса возможно получить самого старшего члена семьи. Здесь используется подзапрос для получения максимальной даты рождения, которая затем используется для фильтрации строк.
+С помощью данного запроса возможно получить самого младшего члена семьи. Здесь используется подзапрос для получения максимальной даты рождения, которая затем используется для фильтрации строк.
 
 #### Подзапросы с ANY, IN, ALL
 
@@ -469,7 +471,7 @@ SELECT поля_таблицы_1 FROM таблица_1
 
 ```sql
 SELECT поля_таблицы_1 
-    FROM (подзапрос) [AS] псевдоним_производной_таблицы
+    FROM (подзапрос) AS псевдоним_производной_таблицы
 ```
 
 Обратите внимание на то, что для производной таблицы обязательно должен указываться её псевдоним, для того, чтобы имелась возможность обратиться к ней в других частях запроса.
@@ -498,7 +500,7 @@ INSERT INTO имя_таблицы [(поле_таблицы, ...)]
 
 ```sql
 INSERT INTO Goods (goodId, goodName, `type`)
-    VALUES (5, 'Table', 2);
+    VALUES (5, 'Table', 2), (6, 'Table2', 1);
 ```
 
 ```sql
@@ -624,130 +626,6 @@ DELETE FROM Products
 DELETE FROM Products;
 ```
 
-<!--
-## Импорт данных (старые скрины из MSSQL)
-
-Теперь, зная синткасис команд INSERT и SELECT, можем разобраться как создать из исходного набора данных словари и загрузить данные в БД с учетом внешних ключей
-
-Допустим есть список агентов (данные полученные от заказчика в виде CSV-файла), у которых есть поля название, тип и т.д. (далее по тексту я её называю *таблица импорта*)
-
-![](../img/sql002.png)
-
-В структуре БД поле "тип агента" создано как внешний ключ на таблицу типов
-
-![](../img/sql001.png)
-
-![](../img/sql003.png)
-
-
-### Заполнение словарей
-
-Для добавления "типов агентов" в таблицу **AgentType** мы будем использовать альтернативный синтаксис `INSERT ... SELECT` 
-
-1. Пишем инструкцию **SELECT**, которая выбирает уникальные записи из *таблицы импорта*:
-
-    ```sql
-    SELECT 
-        DISTINCT Тип_агента
-    FROM
-        agents_import
-    ```
-
-    1. Ключевое слово **DISTINCT** относится только к тому полю, перед которым написано. В нашем случае выбирает уникальные названия типов агентов. 
-    2. Откуда брать поле **Image** в предметной области не написано и в исходных данных его нет. Но т.к. в целевой таблице это поле не обязательное, то можно его пропустить
-
-    Этот запрос можно выполнить отдельно, чтобы проверить что получится
-
-2. После отладки запроса **SELECT** перед ним допишем запрос **INSERT**:
-
-    ```sql
-    INSERT INTO AgentType (Title)
-    SELECT 
-        DISTINCT Тип_агента 
-    FROM
-        agents_import
-    ```
-
-    1. Поле **ID** можно пропустить, оно автоинкрементное и создастся само
-    2. Количество и порядок вставляемых полей `(Title)` должно быть равным количеству выбираемых полей `(Тип_агента)`
-       
-    Если в таблице есть обязательные поля, а нам неоткуда взять для них данные, то мы можем в **SELECT** вставить фиксированные значения (в примере пустая строка): 
-
-        ```sql
-        INSERT INTO AgentType (Title, Image)
-        SELECT 
-            DISTINCT Тип_агента, ''
-        --                       ^^ 
-        FROM
-            agents_import
-        ```
-
-### Заполнение основной таблицы
-
-1. Тоже сначала пишем **SELECT** запрос, чтобы проверить те ли данные получаются
-
-    * напоминаю, что порядок и количество выбираемых и вставляемых полей должны быть одинаковыми
-
-    * в поле **AgentTypeID** мы должны вставить ID соответсвующей записи из таблицы **AgentType**, поэтому выборка у нас из двух таблиц и чтобы не писать перед каждым полем полные названия таблиц мы присваиваем им алиасы
-
-    ```sql
-    SELECT 
-        asi.Наименование_агента, 
-        att.ID, 
-        asi.Юридический_адрес, 
-        asi.ИНН, 
-        asi.КПП, 
-        asi.Директор, 
-        asi.Телефон_агента, 
-        asi.Электронная_почта_агента, 
-        asi.Логотип_агента, 
-        asi.Приоритет
-    FROM 
-        agents_import asi, 
-        AgentType att
-    WHERE 
-        asi.Тип_агента=att.Title
-    ```
-
-    Т.е. мы выбираем перечисленные поля из таблицы **agents_import** и добавляем к ним ID агента у которого совпадает название.
-
-    При выборке из нескольких таблиц исходные данные перемножаются. Т.е. если мы не заполним перед этой выборкой словарь, то `100 * 0 = пустая выборка`.
-
-    Если же мы не укажем условие **WHERE**, то выберутся, к примеру, `100 * 10 = 1000` записей (каждый агент будет в каждой категории). Поэтому важно, чтобы условие **WHERE** выбирало **уникальные** значения.  
-
-    Естественно, количество внешних ключей в таблице может быть больше одного, в таком случае в секции **FROM** перечисляем все используемые словари и в секции **WHERE** перечисляем условия для всех таблиц объединив их логическим выражением **AND**
-
-        ```sql
-        ...
-        WHERE
-            a.Name=b.Name AND a.Title=c.Title AND a.Price=d.Price ...
-        ``` 
-
-    где алиасы b, c, d - словарные таблицы, а алиас "а" - *таблица импорта*
-
-2. Написав и проверив работу выборки (она должна возвращать столько же записей, сколько в *таблице импорта*) дописываем команду вставки данных:
-
-    ```sql
-    INSERT INTO Agent (Title, AgentTypeID, Address, INN, KPP, DirectorName, Phone, Email, Logo, Priority)
-    SELECT 
-        asi.Наименование_агента, 
-        att.ID, 
-        asi.Юридический_адрес, 
-        asi.ИНН, 
-        asi.КПП, 
-        asi.Директор, 
-        asi.Телефон_агента, 
-        asi.Электронная_почта_агента, 
-        asi.Логотип_агента, 
-        asi.Приоритет
-    FROM 
-        agents_import asi, 
-        AgentType att
-    WHERE 
-        asi.Тип_агента=att.Title
-    ```
--->
-
 ## Data Definition Language (DDL)
 
 **Data Definition Language (DDL)** – это группа операторов **определения** данных. Другими словами, с помощью операторов, входящих в эту группы, мы определяем структуру базы данных и работаем с объектами этой базы, т.е. создаем, изменяем и удаляем их.
@@ -768,7 +646,7 @@ CREATE DATABASE [IF NOT EXISTS] db_name
 
 Оператор `CREATE DATABASE` создает базу данных с указанным именем. Если база данных уже существует и не указан ключевой параметр `IF NOT EXISTS`, то возникает ошибка выполнения команды.
 
-Если в названии базы данных присутствуют пробелы или название совпадает с ключевым словом SQL, то название можно экранировать символами обратной кавычки (подобное экранирование применяется и к названиям других сущностей): 
+Если в названии базы данных присутствуют пробелы или название совпадает с ключевым словом SQL, то название можно экранировать символами обратной кавычки (подобное экранирование применяется и к названиям других сущностей и атрибутов): 
 
 ```
 CREATE DATABASE `database` 
@@ -859,7 +737,7 @@ CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
         )
         ```
 
-    * индекс
+    * индекс (альтернативный ключ)
     
         синтаксис:
 
@@ -881,7 +759,7 @@ CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
 
         * `index_name` - название индекса
 
-        * `index_col_name` - название колонки, входящей в ключ индекса: `col_name [(length)]`. Содержимое колонки может быть обрезано по длине `length` 
+        * `index_col_name` - название колонки (колонок), входящей в ключ индекса: `col_name [(length)]`. Содержимое колонки может быть обрезано по длине `length` 
 
         Ключ `UNIQUE` может иметь только различающиеся значения. При попытке добавить новую строку с ключом, совпадающим с существующей строкой, возникает ошибка выполнения команды.
 
@@ -920,18 +798,18 @@ CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
 
         ```sql
         -- таблица "склад"
-        CREATE TABLE `warehouse` (
+        CREATE TABLE `Warehouse` (
             `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
             `title` varchar(100) DEFAULT NULL,
             `quantity` int(11) DEFAULT NULL,
         )
 
         -- таблица "продажи"
-        CREATE TABLE `sales` (
+        CREATE TABLE `Sales` (
             `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
             `warehouse_id` int(11) DEFAULT NULL,
             `quantity` int(11) DEFAULT NULL,
-            CONSTRAINT `sales_FK` 
+            CONSTRAINT `FK_sales_warehouse` 
                 FOREIGN KEY (`warehouse_id`) 
                 REFERENCES `warehouse` (`id`)
         )
@@ -983,7 +861,7 @@ ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]
         ```sql
         -- добавление внешнего ключа в таблицу "продажи"
         ALTER TABLE `sales`
-            ADD CONSTRAINT `sales_FK` 
+            ADD CONSTRAINT `FK_sales_warehouse` 
             FOREIGN KEY (`warehouse_id`) 
             REFERENCES `warehouse` (`id`);
         ```
@@ -1017,12 +895,16 @@ ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]
 
 ## Задание
 
-Написать скрипт, создающий базу данных по ERD вашего курсового проекта.
+Прорешать несколько задач из [SQL Академии](https://sql-academy.org/ru/trainer). Количество не менее 5-ти, на троечку лёгкие, на четверку средние, на пятерку сложные. 
+
+Результаты опубликовать в репозитории (скрины со сложностью задачи, текстом запроса и результатом. ERD не включать)
+
+Пример:
+
+![](../img/sql014.png)
+
+В верхней части пишете текст запроса, в нижней видите результат. Справа есть ERD для базы данных.
 
-<table style="width: 100%;"><tr><td style="width: 40%;">
-<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы
-</a></td><td style="width: 20%;">
-<a href="../readme.md">Содержание
-</a></td><td style="width: 40%;">
-<a href="../articles/sql_view.md">Представления (View)
-</a></td><tr></table>
+Предыдущая лекция | &nbsp; | Следующая лекция
+:----------------:|:----------:|:----------------:
+[Словарь данных](./5_1_1_1_data_dictionary.md) | [Содержание](../readme.md#проектирование-баз-данных) | [Создание базы данных. Импорт данных.](./sql_import.md)

BIN
img/sql014.png