В данной статье рассмотрены основы работы с языком структурированных запросов SQL.
Базой данных является коллекция информации, организованная таким образом, чтобы облегчить доступ, а также эффективное управление и обновление информации. База данных состоит из таблиц, хранящих необходимую информацию. Таблицы хранят и отображают информацию в структурированном формата, состоящем из столбцов и строк. Базы данных часто содержат множество таблиц, разработанных для специфических целей. Каждая таблица включает в себя свой собственный набор полей, основанный на информации, которую он будет хранить.
Таблица имеет определенное количество столбцов, но может иметь любое количество строк.
Первичный ключ (primary key) – поле таблицы, которое уникально идентифицирует записи таблицы. Главные особенности первичных ключей:
Например, таблица содержит запись для каждого имени в телефонной книге. Хорошим выбором для первичного ключа в таблице является уникальное значение ID, так как всегда существует вероятность, что будет несколько людей с одинаковыми именами.
- В таблицах может быть только ОДИН первичный ключ.
- Значение первичного ключа должность быть разным в каждой строке.
SQL (Structed Query Language) – язык структурированных запросов. SQL используется для управления базами данных. MySQL – это система управления базами данных. SQL может:
SQL является стандартом ANSI, но существуют различные версии языка SQL. Большинство программ баз данных SQL имеют свои собственные расширения, в дополнение к SQL стандарту, но все они поддерживают основные команды.
Выражение языка SQL SHOW показывает информацию, содержащую в базе данных и её таблицах. Этот инструмент позволяет следить за содержимым базы данных и напоминать вам о структуре таблиц.
Команда SHOW DATABASES
отображает базы данных, которые управляются сервером. Команда SHOW TABLES
используется для отображения всех таблиц в текущей выбранной базе данных MySQL.
Пример:
Создадим базу данных my_db
CREATE DATABASE my_db;
Проверим, что таблица создалась.
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| my_db |
| mysql |
| performance_schema |
| sys |
+--------------------+
Выберем созданную базу данных для создания таблицы.
USE my_db;
Создадим таблицу customers.
create table customers (
ID INT NOT NULL AUTO_INCREMENT,
FirstName VARCHAR(30),
LastName VARCHAR(30),
TelephoneNumber VARCHAR(15),
PRIMARY KEY (ID)
);
Проверим наличие таблицы.
show tables;
+-----------------+
| Tables_in_my_db |
+-----------------+
| customers |
+-----------------+
Команда SHOW COLUMNS
отображает информацию о столбцах в заданной таблице.
Например:
show columns from customers;
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| ID | int | NO | PRI | NULL | auto_increment |
| FirstName | varchar(30) | YES | | NULL | |
| LastName | varchar(30) | YES | | NULL | |
| TelephoneNumber | varchar(15) | YES | | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
SHOW COLUMNS
отображает следующие значения для каждого столбца таблицы:
Field - название столбца.
Type - тип данных столбца.
Default - присвоенное столбцу значение по-умолчанию.
Extra - может содержать любую дополнительную информацию, доступную для данного столбца.
Выражение SELECT используется для выбора информации из базы данных. Результат сохраняется в результирующей таблице, которая называется result-set. Запрос может получать информацию из выбранных столбцов, или из всех столбцов таблицы. Чтобы создать простое выражение SELECT, укажите имя (имена) столбца (столбцов), который необходим в таблице. Синтаксис выражения SQL SELECT:
SELECT <список_столбцов> FROM <имя_таблицы>
select * from customers;
+----+-----------+----------+-----------------+
| ID | FirstName | LastName | TelephoneNumber |
+----+-----------+----------+-----------------+
| 1 | Johnathan | Smith | 1101 |
| 2 | David | Williams | 1102 |
| 3 | Chloe | Anderson | 2002 |
| 4 | Emily | Adams | 151 |
| 5 | James | Roben | 900 |
+----+-----------+----------+-----------------+
Выведем только столбец FirstName из таблицы.
select FirstName from customers;
+-----------+
| FirstName |
+-----------+
| Johnathan |
| David |
| Chloe |
| Emily |
| James |
+-----------+
SQL позволяет выполнять множество запросов или команд в одно время. Например:
select FirstName from customers; select TelephoneNumber from customers;
+-----------+
| FirstName |
+-----------+
| Johnathan |
| David |
| Chloe |
| Emily |
| James |
+-----------+
+-----------------+
| TelephoneNumber |
+-----------------+
| 1101 |
| 1102 |
| 2002 |
| 151 |
| 900 |
+-----------------+
Каждое SQL-выражение должно заканчиваться точкой с запятой, чтобы указать, что выражение завершено и может быть интерпретировано.
SQL является не чувствительным к регистру. Следующие выражения отдают одинаковый результат.
SELECT FirstName From customers; selecT TelephoneNumber fRom customers;
+-----------+
| FirstName |
+-----------+
| Johnathan |
| David |
| Chloe |
| Emily |
| James |
+-----------+
+-----------------+
| TelephoneNumber |
+-----------------+
| 1101 |
| 1102 |
| 2002 |
| 151 |
| 900 |
+-----------------+
Одно SQL-выражение может быть размещено на одной, или нескольких строках. Кроме этого, несколько SQL выражений могут быть скомбинированы на одной строке. Пробелы и множества строк игнорируются в SQL. Однако, рекомендуется избегать использование ненужных пробелов и пробельных строк.
В одном SQL-выражении можно выбрать несколько столбцов. Для этого необходимо указывать названия столбцов через запятую.
select LastName,FirstName from customers;
+----------+-----------+
| LastName | FirstName |
+----------+-----------+
| Smith | Johnathan |
| Williams | David |
| Anderson | Chloe |
| Adams | Emily |
| Roben | James |
+----------+-----------+
Чтобы выбрать все столбцы необходимо использовать символ звёздочки *
. Например.
select * from customers;
+----+-----------+----------+-----------------+
| ID | FirstName | LastName | TelephoneNumber |
+----+-----------+----------+-----------------+
| 1 | Johnathan | Smith | 1101 |
| 2 | David | Williams | 1102 |
| 3 | Chloe | Anderson | 2002 |
| 4 | Emily | Adams | 151 |
| 5 | James | Roben | 900 |
+----+-----------+----------+-----------------+
В ситуациях, когда есть множество повторных записией в таблице, может иметь больше смысла возврат только уникальных записей, вместо извлечения дубликатов.
Ключевое слово языка SQL DISTINCT используется в сочетании с SELECT для устранения всех повторных записей и возврата только уникальных. Базовых синтаксис ключевого слова DISTINCT выглядит следующим образом:
SELECT DISTINCT имя_столбца1,имя_столбца2 FROM имя_таблицы;
Пример: Просмотрим полную таблицу customers.
select * from customers;
+----+-----------+----------+-----------------+------------+
| ID | FirstName | LastName | TelephoneNumber | City |
+----+-----------+----------+-----------------+------------+
| 1 | Johnathan | Smith | 1101 | New York |
| 2 | David | Williams | 1102 | Moscow |
| 3 | Chloe | Anderson | 2002 | New York |
| 4 | Emily | Adams | 151 | Berlin |
| 5 | James | Roben | 900 | London |
| 6 | John | Strong | 1022 | Kalinigrad |
+----+-----------+----------+-----------------+------------+
Заметим что в таблице повторяются названия в столбце City. Выведем только уникальные значения строк столбца City.
select distinct City from customers;
+------------+
| City |
+------------+
| New York |
| Moscow |
| Berlin |
| London |
| Kalinigrad |
+------------+
Ключевое слово DISTINCT извлекает только уникальные значения.
По-умолчанию, все результаты, которые удовлетворяют условиям, указанным в SQL выражении, возвращаются. Однако, иногда нужно получить только часть записей. В MySQL это достигается с помощью ключевого слова LIMIT. Синтаксис ключевого слова LIMIT следующий.
SELECT список_столбцов FROM имя_таблицы LIMIT [число_записей];
Например, так выглядит изначальная таблица.
select * from customers;
+----+-----------+----------+-----------------+------------+
| ID | FirstName | LastName | TelephoneNumber | City |
+----+-----------+----------+-----------------+------------+
| 1 | Johnathan | Smith | 1101 | New York |
| 2 | David | Williams | 1102 | Moscow |
| 3 | Chloe | Anderson | 2002 | New York |
| 4 | Emily | Adams | 151 | Berlin |
| 5 | James | Roben | 900 | London |
| 6 | John | Strong | 1022 | Kalinigrad |
+----+-----------+----------+-----------------+------------+
Мы можем получить первые пять записей из таблицы customers.
SELECT ID, FirstName, LastName, City FROM customers LIMIT 5;
По-умолчанию, все результаты, которые удовлетворяют условиям, указанным в SQL выражении, возращаются.
Также можем подобрать набор записей из определенного смещения. В следующем примере мы подобрали четыре записи, начиная со 2 по 4.
select ID,Firstname,LastName,City from customers LIMIT 1,3;
+----+-----------+----------+----------+
| ID | Firstname | LastName | City |
+----+-----------+----------+----------+
| 2 | David | Williams | Moscow |
| 3 | Chloe | Anderson | New York |
| 4 | Emily | Adams | Berlin |
+----+-----------+----------+----------+
Выведены значения начиная с 0 индекса по 3 (0+3).
MySQL производит отсчёт с нуля. Поэтому в демонстрируемой команде указаны значения LIMIT 1 и 3, а не 2 и 4.
В SQL возможно указать имя таблицы перед именем столбца, разделяя их точкой. Следующие выражения эквиваленты.
select City from customers;
select customers.City;
Вышеуказанный синтаксис customers.City называется полным именем этого столбца.
Данная форма написания полезна при работе со множеством таблиц, которые могут иметь одинаковые названия столбцов.
ORDER BY используется с SELECT для сортировки возвращаемой информации. Следующий пример сортирует нашу таблицу customers по столбцу FirstName.
select * from customers ORDER BY FirstName;
+----+-----------+----------+-----------------+------------+
| ID | FirstName | LastName | TelephoneNumber | City |
+----+-----------+----------+-----------------+------------+
| 3 | Chloe | Anderson | 2002 | New York |
| 2 | David | Williams | 1102 | Moscow |
| 4 | Emily | Adams | 151 | Berlin |
| 5 | James | Roben | 900 | London |
| 6 | John | Strong | 1022 | Kalinigrad |
| 1 | Johnathan | Smith | 1101 | New York |
+----+-----------+----------+-----------------+------------+
Строки стали упорядочены по алфавиту по столбцу FirstName.
По-умолчанию, ключевое слово ORDER BY сортирует результаты в возрастающем порядке.
ORDER BY может сортировать информацию по нескольким столбцам. При использовании ORDER BY с более чем одним столбцом, разделяйте список запятыми. Таблица customers отображает следующие записи:
select * from customers;
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 2 | David | Williams | 1102 | Moscow | 25 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 5 | James | Roben | 900 | London | 19 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
+----+-----------+------------+-----------------+------------+------+
Чтобы отсортировать по LastName и Age:
select * from customers order by LastName, Age;
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 5 | James | Roben | 900 | London | 19 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 2 | David | Williams | 1102 | Moscow | 25 |
+----+-----------+------------+-----------------+------------+------+
Так как у нас два значения Smith, они будут отсортированы по столбцу Age в возрастающем порядке.
Команда ORDER BY начинает сортировку в том же порядке, в котором находятся столбцы. Сначала будет отсортирован первый столбец, потом второй и так далее.
<заполнить_поле> TABLES;
SELECT <заполнить_поле> name <заполнить_поле> students <заполнить_поле> name;
Условие WHERE Используется для выполнения только тех записей, которые соответствуют указанному критерию. Синтаксис для условия WHERE:
SELECT список_столбцов FROM имя_таблицы WHERE условие;
Рассмотрим следующую таблицу:
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 2 | David | Williams | 1102 | Moscow | 25 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 5 | James | Roben | 900 | London | 19 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
+----+-----------+------------+-----------------+------------+------+
Из данной таблицы выберем определенную запись с помощью SELECT:
select * from customers where ID = 7;
+----+-----------+----------+-----------------+--------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+----------+-----------------+--------+------+
| 7 | Julia | Roberts | 6451 | London | 35 |
+----+-----------+----------+-----------------+--------+------+
Условие WHERE используется для выполнения только тех записей, которые соответствуют указанному критерию.
Условные операторы и логические операторы используются в условии WHERE для фильтрации выбираемой информации. Следующие операторы сравнения могут быть использованы в условии WHERE:
Оператор | Описание |
---|---|
= | Равно |
!= | Не равно |
> | Больше, чем |
< | Меньше, чем |
>= | Больше, либо равно |
<= | Меньше, либо равно |
BETWEEN | Между включенного диапазонаа |
Например, мы можем отобразить все имена, отображеение в нашей таблице, кроме одного с ID 5.
SELECT * FROM customers WHERE ID != 5;
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 2 | David | Williams | 1102 | Moscow | 25 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
+----+-----------+------------+-----------------+------------+------+
Как видно, запись с ID = 5 исключена из списка.
Оператор BETWEEN выбирает значения внутри диапазона. Первое значение должно быть нижней границей, а второе значение верхней границей. Синтаксис условия BETWEEN выглядит следующим образом.
SELECT имя_столбцов FROM имя_таблицы WHERE имя_столбца BETWEEN значение1 AND значение2;
Следующее SQL выражение выбирает все записи с ID между 3 и 7:
select * from customers where id between 3 and 7;
+----+-----------+----------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+----------+-----------------+------------+------+
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 5 | James | Roben | 900 | London | 19 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
+----+-----------+----------+-----------------+------------+------+
Как видим, нижняя граница и верхняя граница включены в диапазон.
При работе с текстовыми столбцами, заключайте любой текст в выражении в одинарные кавычки (’).
select id, firstname, lastname, city from customers where city = 'new york';
+----+-----------+----------+----------+
| id | firstname | lastname | city |
+----+-----------+----------+----------+
| 1 | Johnathan | Smith | New York |
| 3 | Chloe | Anderson | New York |
+----+-----------+----------+----------+
Если текст содержит апостроф (одинарная кавычка), то необходимо использовать два символа одиночной кавычки, чтобы избежать апострофа. Например:
Can''t
.
Логические операторы могут использоваться для комбинации двух Булевых значений и возврата результата верно (true), ложь (false) или null. Могут быть использованы следуюие операторы.
Оператор | Описание |
---|---|
AND | ВЕРНО, если оба выражения ВЕРНЫ |
OR | ВЕРНО, если одно из выражений ВЕРНО |
IN | ВЕРНО, если операнд равен одному из выражений в списке |
NOT | Возвращает ВЕРНО, если выражение НЕ ВЕРНО |
При получении информации с помощью выражения SELECT, используйте логические операторы в условии WHERE для комбинации нескольких условий.
Если вы хотите выбрать строки, которые удовлетворяют всем заданным условиям, используйте логический оператор AND.
Используем следующую таблицу:
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 2 | David | Williams | 1102 | Moscow | 25 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 5 | James | Roben | 900 | London | 19 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
+----+-----------+------------+-----------------+------------+------+
Чтобы найти имена в таблице с возрастом от 30 до 40 лет, настройте запрос следующим образом:
select id,firstname,lastname,age from customers where age >=30 and age <= 40;
+----+-----------+----------+------+
| id | firstname | lastname | age |
+----+-----------+----------+------+
| 4 | Emily | Adams | 30 |
| 7 | Julia | Roberts | 35 |
| 16 | Clara | Smith | 37 |
+----+-----------+----------+------+
Вы можете комбинировать столько условий, сколько необходимо для получения желаемых результатов.
Если необходимо выбрать строки, которые удовлетворяют по меньшей мере обному из заданных условий, можно использовать логический оператор OR (ИЛИ). Например, если необходимо найти клиентов (customers), которые живут либо в Нью-Йорке (New-York), либо в Чикаго (Chicago), то запрос может выглядеть следующем образом:
SELECT * FROM customers WHERE City = 'New York' OR City = 'Chicago';
+----+-----------+----------+-----------------+----------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+----------+-----------------+----------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
+----+-----------+----------+-----------------+----------+------+
Вы можете использовать OR для двух или более условий.
В SQL условия AND и OR могут быть комбинированы для тестирования множества условий в запросе. Эти два оператора называются конъюнктивными операторами. При комбинации этих условий важно использовать скобки для упорядочивания вычислений всех известных условий.
Рассмотрим следующую таблицу:
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 2 | David | Williams | 1102 | Moscow | 25 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 5 | James | Roben | 900 | London | 19 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
+----+-----------+------------+-----------------+------------+------+
Нижеуказанное выражение выбирает всех клиентов из города New-York И выбирает тех, у кого возраст равен 30 ИЛИ 35:
SELECT * FROM customers WHERE City = 'New York' AND (Age=21 OR Age=25);
+----+-----------+----------+-----------------+----------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+----------+-----------------+----------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
+----+-----------+----------+-----------------+----------+------+
Вы можете тестировать любое необходимое количество условий.
Оператор IN используется тогда, когда вы хотите сравнить столбец более с чем одним значением. Например, возможно вам понадобится выбрать всех клиентов из городов New York, Los Angeles и Chicago. С условием OR SQL-запрос будет выглядеть следующим образом.
SELECT * FROM customers WHERE City = 'New York' OR City = 'Los Angeles' OR City = 'Chicago';
+----+-----------+----------+-----------------+----------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+----------+-----------------+----------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
+----+-----------+----------+-----------------+----------+------+
Оператор IN используется тогда, когда вы хотите сравнить столбец больше чем с одним значением.
Вы можете получить такой же результат с условием IN вместо использования нескольких условий OR.
SELECT * FROM customers WHERE City IN ('New York', 'Los Angeles', 'Chicago');
+----+-----------+----------+-----------------+----------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+----------+-----------------+----------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
+----+-----------+----------+-----------------+----------+------+
Обратите внимание на использование скобок в синтаксисе;
Оператор NOT IN позволяет вам исключать список определенных значений из результирующего набора. Если мы добавим ключевое слово NOT перед IN в нашем предыдущем запросе, то клиенты, живущие в этих городах будут исключены:
SELECT * FROM customers WHERE City NOT IN ('New York', 'Los Angeles', 'Chicago');
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 2 | David | Williams | 1102 | Moscow | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 5 | James | Roben | 900 | London | 19 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
+----+-----------+------------+-----------------+------------+------+
Оператор NOT IN позволяет вам исключать список оперделенных значений из результирующего набора.
Фунция CONCAT используется для конкатенации двух и более текстовых значений, и для возврата полученной строки. Выполним объединение FirstName с City, разделив их запятой.
SELECT CONCAT(FirstName, ', ' , City) FROM customers;
+--------------------------------+
| CONCAT(FirstName, ', ' , City) |
+--------------------------------+
| Johnathan, New York |
| David, Moscow |
| Chloe, New York |
| Emily, Berlin |
| James, London |
| John, Kalinigrad |
| Julia, London |
| Emely, Frankfurt |
| Albert, Paris |
| Kolia, Paris |
| Pavel, Praga |
| Natalia, Samara |
| Aurelius, Samara |
| Alexandra, Talin |
| Samson, Rome |
| Clara, Norilsk |
+--------------------------------+
Функция CONCAT() принимает два параметра или более.
Конкатенация образует новый столбец. Названием столбца по-умолчанию будет функция CONCAT. Вы можете присвоить своё имя образованному столбцу, с помощью ключевого слова AS:
SELECT CONCAT(FirstName,', ', City) AS new_column FROM customers;
+---------------------+
| new_column |
+---------------------+
| Johnathan, New York |
| David, Moscow |
| Chloe, New York |
| Emily, Berlin |
| James, London |
| John, Kalinigrad |
| Julia, London |
| Emely, Frankfurt |
| Albert, Paris |
| Kolia, Paris |
| Pavel, Praga |
| Natalia, Samara |
| Aurelius, Samara |
| Alexandra, Talin |
| Samson, Rome |
| Clara, Norilsk |
+---------------------+
Конкатенация образует новый столбец.
Арифметические операторы выполняют арифметические операции с числовыми операндами. Арифметические операторы включают в сеюя сложение (+), вычитание (-), умножение (*) и деление (/).
Следующая таблица employees отображает имена и зарплаты работников:
+----+-----------+------------+--------+
| ID | FirstName | LastName | Salary |
+----+-----------+------------+--------+
| 1 | Johnathan | Smith | 25000 |
| 2 | David | Williams | 27000 |
| 3 | Chloe | Anderson | 27000 |
| 4 | Emily | Adams | 42000 |
| 5 | James | Roben | 40000 |
| 6 | John | Strong | 20000 |
| 7 | Julia | Roberts | 120000 |
| 8 | Emely | Roads | 39000 |
| 9 | Albert | Calaw | 48000 |
| 10 | Kolia | Varow | 50000 |
| 11 | Pavel | Kotov | 61000 |
| 12 | Natalia | Bochkareva | 61000 |
| 13 | Aurelius | Soul | 30000 |
| 14 | Alexandra | Damahwalk | 34000 |
| 15 | Samson | Ropotorod | 32000 |
| 16 | Clara | Smith | 70000 |
+----+-----------+------------+--------+
Нижеуказанный пример добавляет 500 к зарплате каждого работника и выбирает результат:
SELECT ID, FirstName, LastName, Salary+500 AS Salary FROM employees;
+----+-----------+------------+--------+
| ID | FirstName | LastName | Salary |
+----+-----------+------------+--------+
| 1 | Johnathan | Smith | 25500 |
| 2 | David | Williams | 27500 |
| 3 | Chloe | Anderson | 27500 |
| 4 | Emily | Adams | 42500 |
| 5 | James | Roben | 40500 |
| 6 | John | Strong | 20500 |
| 7 | Julia | Roberts | 120500 |
| 8 | Emely | Roads | 39500 |
| 9 | Albert | Calaw | 48500 |
| 10 | Kolia | Varow | 50500 |
| 11 | Pavel | Kotov | 61500 |
| 12 | Natalia | Bochkareva | 61500 |
| 13 | Aurelius | Soul | 30500 |
| 14 | Alexandra | Damahwalk | 34500 |
| 15 | Samson | Ropotorod | 32500 |
| 16 | Clara | Smith | 70500 |
+----+-----------+------------+--------+
Круглые скобки могут использоваться, чтобы заставить операцию принимать приоритет над любыми другими операторами. Они также используются для улучшения читаемости кода.
Функция UPPER конвертирует все буквы в указанной строке в верхний регистр. Функция LOWER конвертирует строку в нижний регистр. Следующий SQL-запрос преобразует все LastNames в верхний регистр:
SELECT FirstName, UPPER(LastName) AS LastName FROM employees;
+-----------+------------+
| FirstName | LastName |
+-----------+------------+
| Johnathan | SMITH |
| David | WILLIAMS |
| Chloe | ANDERSON |
| Emily | ADAMS |
| James | ROBEN |
| John | STRONG |
| Julia | ROBERTS |
| Emely | ROADS |
| Albert | CALAW |
| Kolia | VAROW |
| Pavel | KOTOV |
| Natalia | BOCHKAREVA |
| Aurelius | SOUL |
| Alexandra | DAMAHWALK |
| Samson | ROPOTOROD |
| Clara | SMITH |
+-----------+------------+
Если в строке есть символы, которые не являются буквами, то функция не будет вляить на них.
Функция SQRT возвращает квадратный корень заданного значения в агрументе. Рассчитаем квадратный корень каждой зарплаты.
SELECT Salary, SQRT(Salary) FROM employees;
+--------+--------------------+
| Salary | SQRT(Salary) |
+--------+--------------------+
| 25000 | 158.11388300841898 |
| 27000 | 164.31676725154983 |
| 27000 | 164.31676725154983 |
| 42000 | 204.93901531919198 |
| 40000 | 200 |
| 20000 | 141.4213562373095 |
| 120000 | 346.41016151377545 |
| 39000 | 197.48417658131498 |
| 48000 | 219.08902300206645 |
| 50000 | 223.60679774997897 |
| 61000 | 246.9817807045694 |
| 61000 | 246.9817807045694 |
| 30000 | 173.20508075688772 |
| 34000 | 184.39088914585776 |
| 32000 | 178.88543819998318 |
| 70000 | 264.5751311064591 |
+--------+--------------------+
В случае использования функции AVG, возвращается среднее значение числового столбца:
SELECT AVG(Salary) FROM employees;
+-------------+
| AVG(Salary) |
+-------------+
| 45375.0000 |
+-------------+
Другой способ сделать SQRT использовать POWER с показателем 1/2. Однако, в этом случае SQRT работает быстрее POWER.
Функция SUM используется для подсчёта суммы зарплат в таблице employees, наш SQL запрос должен выглядеть следующим образом:
SELECT SUM(Salary) FROM employees;
+-------------+
| SUM(Salary) |
+-------------+
| 726000 |
+-------------+
Подзапрос – это запрос внутри другого запроса. Рассмотрим следующий пример. Нам понадобиться список всех работников, чьи зарплаты выше средней. Сперва посчитаем среднюю зарплату:
SELECT AVG(Salary) FROM employees;
Теперь, когда мы знаем среднюю зарплату, мы можем использовать простое выражение WHERE для отображения списка зарплат, которые больше этого числа.
SELECT FirstName, Salary FROM employees WHERE Salary > 3100 ORDER BY Salary DESC;
+-----------+--------+
| FirstName | Salary |
+-----------+--------+
| Julia | 120000 |
| Clara | 70000 |
| Pavel | 61000 |
| Natalia | 61000 |
| Kolia | 50000 |
| Albert | 48000 |
| Emily | 42000 |
| James | 40000 |
| Emely | 39000 |
| Alexandra | 34000 |
| Samson | 32000 |
| Aurelius | 30000 |
| David | 27000 |
| Chloe | 27000 |
| Johnathan | 25000 |
| John | 20000 |
+-----------+--------+
Ключевое слово DESC сортирует результаты в порядке убывания. По аналогии, ASC сортирует результаты в порядке возрастания.
Один подзапрос выведет такой же результат намного проще.
SELECT FirstName, Salary FROM employees WHERE Salary > (SELECT AVG(Salary) FROM employees) ORDER BY Salary DESC;
+-----------+--------+
| FirstName | Salary |
+-----------+--------+
| Julia | 120000 |
| Clara | 70000 |
| Pavel | 61000 |
| Natalia | 61000 |
| Kolia | 50000 |
| Albert | 48000 |
+-----------+--------+
Закрывайте подзапросы в скобки. Также, обратите внимание, что нет точки с запятой в конце подзапроса, потому что он является частью нашего запроса.
Ключевое слово LIKE полезно при указании условии поиска внутри вашего выражения WHERE.
SELECT имя столбца(ов) FROM имя_таблицы WHERE имя_столбца LIKE шаблон;
Поиск по шаблону в SQL позволяет вам использовать “_” для соответствия любому одиночному символу, и “%” для соответствия произвольному количеству символов (включая нулевое количество символов).
Например, чтобы выбрать работников, чьи FirstName начинаются с буквы А, вам необходимо использовать следующий запрос:
SELECT * FROM employees WHERE FirstName LIKE 'A%';
+----+-----------+-----------+--------+
| ID | FirstName | LastName | Salary |
+----+-----------+-----------+--------+
| 9 | Albert | Calaw | 48000 |
| 13 | Aurelius | Soul | 30000 |
| 14 | Alexandra | Damahwalk | 34000 |
+----+-----------+-----------+--------+
В качестве другого примера, следующий SQL-запрос выбираает всех работников с LastName заканчивающимся буквой “s”:
SELECT * FROM employees WHERE LastName LIKE '%s';
+----+-----------+----------+--------+
| ID | FirstName | LastName | Salary |
+----+-----------+----------+--------+
| 2 | David | Williams | 27000 |
| 4 | Emily | Adams | 42000 |
| 7 | Julia | Roberts | 120000 |
| 8 | Emely | Roads | 39000 |
+----+-----------+----------+--------+
Подстановочный символ % может быть использован множество раз внутри одного шаблона.
Функция MIN используется для возврата минимального значения выражения в операторе SELECT. Например, вы можете узнать минимальную зарплату среди работников.
SELECT MIN(Salary) AS Salary FROM employees;
+--------+
| Salary |
+--------+
| 20000 |
+--------+
Все SQL функции могут быть скомбинированы вместе для создания одного выражения.
SELECT * FROM <вставить_поле> WHERE <вставить_поле> = 'MIT';
Все отображаемые до этого времени запросы работали только с одной таблицей. Одной из наиболее полезных особенностей SQL является возможность комбинирования информации из дввух и более таблиц.
В двух нижеуказанных таблицах, таблица customers хранит информацию о клиентах:
+----+-----------+------------+-----------------+------------+------+
| ID | FirstName | LastName | TelephoneNumber | City | Age |
+----+-----------+------------+-----------------+------------+------+
| 1 | Johnathan | Smith | 1101 | New York | 21 |
| 2 | David | Williams | 1102 | Moscow | 25 |
| 3 | Chloe | Anderson | 2002 | New York | 25 |
| 4 | Emily | Adams | 151 | Berlin | 30 |
| 5 | James | Roben | 900 | London | 19 |
| 6 | John | Strong | 1022 | Kalinigrad | 18 |
| 7 | Julia | Roberts | 6451 | London | 35 |
| 8 | Emely | Roads | 6451 | Frankfurt | 22 |
| 9 | Albert | Calaw | 1321 | Paris | 20 |
| 10 | Kolia | Varow | 669035 | Paris | 20 |
| 11 | Pavel | Kotov | 3310 | Praga | 50 |
| 12 | Natalia | Bochkareva | 338 | Samara | 21 |
| 13 | Aurelius | Soul | 1994 | Samara | 26 |
| 14 | Alexandra | Damahwalk | 7790 | Talin | 23 |
| 15 | Samson | Ropotorod | 901 | Rome | 47 |
| 16 | Clara | Smith | 9115 | Norilsk | 37 |
+----+-----------+------------+-----------------+------------+------+
Таблица orders хранит информацию о индивидуальных заказах с соответствующим количеством:
+----+------------+-------------+--------+
| ID | Name | Customer_ID | Amount |
+----+------------+-------------+--------+
| 1 | Book | 16 | 300 |
| 2 | Box | 15 | 200 |
| 3 | Toy | 14 | 100 |
| 4 | Flowers | 13 | 2000 |
| 5 | Cake | 12 | 500 |
| 6 | Stone | 11 | 3000 |
| 7 | Smartphone | 10 | 5000 |
| 8 | Keyboard | 9 | 2500 |
| 9 | Stickers | 8 | 900 |
| 10 | Clutch | 7 | 10000 |
| 11 | Oil | 6 | 2050 |
| 12 | Headphones | 5 | 5700 |
| 13 | Souvenir | 4 | 7200 |
| 14 | Scarf | 3 | 1800 |
| 15 | Lighter | 2 | 400 |
| 16 | Ink | 1 | 600 |
+----+------------+-------------+--------+
В SQL, соединение таблиц означает комбинацию данных из двух и более таблиц. Соединение таблиц создаёт временную таблицу, отображающую информацию из объединенных таблиц.
Вместо того, чтобы хранить имя клиента в двух таблицах, таблица orders содержит ссылку на ID клиента, который находится в таблице клиентов. Такой подход является более эффективным в отличие от хранения одного и того же занчения в двух таблицах. Чтобы иметь возможность выбора информации из двух таблиц, нам необходимо их объединить.
Для того, чтобы объединить две таблицы, укажите их в списке через запятую в выражении FROM:
SELECT customers.ID, customers.FirstName, orders.Name, orders.Amount FROM customers, orders WHERE customers.ID=orders.Customer_ID ORDER BY customers.ID;
Каждая таблица содержит столбцы ID и Name, так что для выбора правильного ID и Name используется полностью квалифицированные имена.
Обратите внимание, что выражение WHERE “объединяет” таблицы, при условии, что ID таблицы customers должно быть равно customer_ID таблицы orders.
Результат использования предыдущего выражения:
+----+-----------+------------+--------+
| ID | FirstName | Name | Amount |
+----+-----------+------------+--------+
| 1 | Johnathan | Ink | 600 |
| 2 | David | Lighter | 400 |
| 3 | Chloe | Scarf | 1800 |
| 4 | Emily | Souvenir | 7200 |
| 5 | James | Headphones | 5700 |
| 6 | John | Oil | 2050 |
| 7 | Julia | Clutch | 10000 |
| 8 | Emely | Stickers | 900 |
| 9 | Albert | Keyboard | 2500 |
| 10 | Kolia | Smartphone | 5000 |
| 11 | Pavel | Stone | 3000 |
| 12 | Natalia | Cake | 500 |
| 13 | Aurelius | Flowers | 2000 |
| 14 | Alexandra | Toy | 100 |
| 15 | Samson | Box | 200 |
| 16 | Clara | Book | 300 |
+----+-----------+------------+--------+
В возвращаемой информации отображены заказы клиента и их количество.
Указывайте несколько названий таблиц в выражении FROM через запятую.
Пользовательские имена могут быть также использованы для таблиц. Вы можете сократить выражение объединения, с помощью установки таблице псевдонима:
SELECT ct.ID, ct.FirstName, ord.Name, ord.Amount FROM customers AS ct, orders AS ord WHERE ct.ID=ord.Customer_ID ORDER BY ct.ID;
+----+-----------+------------+--------+
| ID | FirstName | Name | Amount |
+----+-----------+------------+--------+
| 1 | Johnathan | Ink | 600 |
| 2 | David | Lighter | 400 |
| 3 | Chloe | Scarf | 1800 |
| 4 | Emily | Souvenir | 7200 |
| 5 | James | Headphones | 5700 |
| 6 | John | Oil | 2050 |
| 7 | Julia | Clutch | 10000 |
| 8 | Emely | Stickers | 900 |
| 9 | Albert | Keyboard | 2500 |
| 10 | Kolia | Smartphone | 5000 |
| 11 | Pavel | Stone | 3000 |
| 12 | Natalia | Cake | 500 |
| 13 | Aurelius | Flowers | 2000 |
| 14 | Alexandra | Toy | 100 |
| 15 | Samson | Box | 200 |
| 16 | Clara | Book | 300 |
+----+-----------+------------+--------+
Как видите, мы сократили имена таблиц, которые мы использовали в нашем запросе.
Типы JOIN (объединений), которые могут быть использованы в MySQL:
INNER JOIN (Внутреннее объединение) эквивалентно JOIN. Оно возвращает строки, если они совпадаают в таблицах.
SELECT имя_столбца(ов) FROM таблица1 INNER JOIN таблица2 ON таблица1.имя_столбца1=таблица2.имя_столбца2;
Обратите внимание на ключевое слово ON, указывающее на условие внутреннего объединения.
Нижеуказанное изображение демонстрирует, как работает INNER JOIN:
Возвращаются только совпадающие записи.
LEFT JOIN возвращает все строки из левой таблицы, даже если нет соответствий в правой таблице.
Это значит, что если нет соответствий в выражении ON в таблице справа, объединение будет возвращать строки из первой таблицы в результат.
Базовый синтаксис объединения LEFT JOIN выглядит следующим образом.
SELECT таблица1.имя_столбца1, таблица2.имя_столбца2 FROM таблица1 LEFT OUTER JOIN таблица2 ON таблица1.имя_столбца = таблица2.имя_столбца;
Ключевое слово OUTER опционально и может быть опущено.
Нижеуказанное изображение демонстрирует, как работает LEFT JOIN:
Рассмотрим следующие таблицы. customers:
ВСТАВИТЬ ТАБЛИЦУ СЮДА
items:
ВСТАВИТЬ ТАБЛИЦУ СЮДА
Следующие SQL выражение выведет всех клиентов и все вещи, которые у них есть:
SELECT customers.Name, items.Name FROM customers LEFT OUTER JOIN items IN customers.ID=items.Seller_id;
ВСТАВИТЬ РЕЗУЛЬТАТ СЮДА
В результате имеются все строки из левой таблицы и соответствующие данных и правой таблицы.
Если совпадение не найдено для конкретной строки, то будет возвращено значение NULL.
RIGHT JOIN возвращает все строки из правой таблицы, даже если нет соответствий в левой таблице.
Базовый синтаксис объединения RIGHT JOIN выглядит следующим образом:
SELECT таблица1.имя_столбца1, таблица2.имя_столбца2 FROM таблица1 RIGHT OUTER JOIN таблица2 ON таблица1.имя_столбца = таблица2.имя_столбца;
Ключевое слово OUTER является опциональным и может быть опущено.
Рассмотрим тот же пример из предыдущего урока, но в этот раз с объединением RIGHT JOIN:
SELECT customers.Name, items.Name FROM customers RIGHT JOIN items ON customers.ID=items.Seller_id;
ВСТАВИТЬ РЕЗУЛЬТАТ СЮДА
Объединение RIGHT JOIN возвращает все строки из правой таблицы (items), даже при отсутствии соответствий в левой таблице (customers).
Существуют и другие типы объединений в языке SQL, но они не поддерживаются в MySQL.
Время от времени, может понадобиться комбинация информации из нескольких таблиц в один набор данных. Это может использоваться в таблицах с аналогичными данными внутри обной базы данных, или может быть необходимость объединения аналогичной информации между базами данных, или даже на сервере.
Чтобы это сделать, используем операторы UNION и UNION ALL.
UNION комбинирует несколько наборов данных в один набор и убирает любые существующие дубликаты. UNION ALL комбинирует несколько наборов данных в один набор, но не убирает дублирующие строки.
UNION ALL быстрее, чем UNION, потому что он не выполняет операцию удаления дубликатов в наборе данных.
Оператор UNION используется для комбинирования наборов результатов двух и более выражений SELECT.
Все выражения SELECT внутри UNION должны иметь одинаковое количество столбцов. Столбцы также должны иметь одинаковые типы данных. Также, столбцы в каждом выражении SELECT должны быть в одинаковом порядке. Синтаксис оператора UNION выглядит следующим образом:
SELECT имя_столбца(ов) FROM таблица1
UNION
SELECT имя_столбца(ов) FROM таблица2;
Первая из двух таблиц:
ВСТАВИТЬ ТАБЛИЦУ СЮДА
Вторая из двух таблиц:
ВСТАВИТЬ ТАБЛИЦУ СЮДА
SELECT ID, FirstName, LastName, City FROM First
UNION
SELECT ID, FirstName, LastName, City FROM Second;
Результат запроса:
ВСТАВИТЬ РЕЗУЛЬТАТ СЮДА
Как видно, дубликаты были убраны.
СОВЕТ: Если столбцы не совпадают в точности по всем запросам, то возможно использовать значение NULL (или любое другое) следующим образом:
SELECT FirstName, LastName, Company FROM businessContacts
UNION
SELECT FirstName, LastName, NULL
FROM otherContacts;
Оператор UNION используется для комбинирования наборов результатов двух и более выражений SELECT.
UNION ALL выбирает все строки из каждой таблицы и комбинирует их в одну таблицу. Следующее SQL выражение использует UNION ALL для выбора информации из первой и второй таблиц:
SELECT ID, FirstName, LastName, City FROM First
UNION ALL
SELECT ID, FirstName, LastName, City FROM Second
Результирующая таблица:
ВСТАВИТЬ ТАБЛИЦУ СЮДА
Как видно, в результате набор также содержит дубликаты строк.
Таблицы SQL хранят данные в строках, одна стройка после другой. Выражение INSERT INTO используется для добавления новых строк информации в таблицу базы данных. Синтаксис SQL INSERT INTO выглядит так:
INSERT INTO имя_таблицы VALUES (значение1, значение2, значение3, ...);
Убедитесь, что значения находятся в том же порядке, что и столбцы в таблице.
Рассмотрим следующую таблицу Employees:
ВСТАВИТЬ ТАБЛИЦУ СЮДА
Используйте следующее SQL выражение для вставки новой строки:
INSERT INTO Employees VALUES (8, 'Anthony', 'Young', 35);
Значения разделяются запятыми, а их порядок соответсвует столбцам в таблице.
СЮДА ВСТАВИТЬ РЕЗУЛЬТАТ
При вставке записей в таблицу с помощью выражения SQL INSERT, вы должны предоставить значения для каждого столбц, который не имеет значения по-умолчанию или не поддерживает NULL.