Sql join что это

SQL JOIN: руководство по объединению таблиц

Перевод первой части статьи «SQL Joins Tutorial: Cross Join, Full Outer Join, Inner Join, Left Join, and Right Join».

Операции объединения в SQL позволяют нашим реляционным базам данных быть… хм… реляционными (англ. relational — «относительный»). Они дают нам возможность реконструировать наши отдельные базы данных с учетом отношений между ними, а это важно для наших приложений.

В этой статье вы рассмотрим все виды JOIN в SQL и расскажем, как ими пользоваться.

В первой части статьи:

(Спойлер: мы рассмотрим пять разных видов объединений, но на самом деле вам нужно знать только два из них!)

Что такое JOIN?

JOIN это операция объединения двух строк в одну. Эти строки обычно бывают из двух разных таблиц, но это не обязательно.

Прежде чем мы разберем, как писать JOIN-ы, давайте посмотрим, как выглядит объединение таблиц.

Возьмем для примера систему, в которой хранится информация о пользователях и их адресах.

Таблица, хранящая информацию о пользователях, может выглядеть следующим образом:

А таблица с адресами может быть такой:

Чтобы получить информацию и о пользователе, и о его адресе, мы можем написать два разных запроса. Но в идеале можно написать один запрос и получить все необходимые сведения в одном ответе.

Именно для этого, собственно, и нужны операции объединения!

Чуть позже мы рассмотрим, как составлять подобные запросы, а пока взгляните, как может вы глядеть результат объединения таблиц:

Мы видим всех наших пользователей сразу с их адресами.

Но операции объединения позволяют не просто выводить такие вот комбинированные сведения. У них есть еще одна важная функция: с их помощью можно получать отфильтрованные результаты.

Теперь, когда вы поняли, для чего вообще нужны операции объединения, давайте приступим к написанию запросов!

Настройка базы данных

Прежде чем писать какие-либо запросы, нужно настроить базу данных.

Для примеров в этой статье будет использоваться PostgreSQL, но запросы и концепции, показанные здесь, легко применимы в любой другой современной СУБД (MySQL, SQL Server и т. д.).

Для работы с нашей базой данных PostgreSQL мы будем пользоваться интерактивной cli-программой psql. Если у вас установлен другой клиент, вы прекрасно можете работать с ним!

Теперь давайте воспользуемся интерактивной консолью (запустив команду psql ) и подключимся к только что созданной базе данных при помощи команды \c :

Примечание: в примерах я подчистил вывод, чтобы их было легче читать. Поэтому не волнуйтесь, что показанный здесь output не в точности совпадает с тем, что вы видите в своем терминале.

Я советую вам прорабатывать запросы, которые мы будем составлять, писать их вместе со мной и запускать. Работая с примерами, вы поймете и запомните куда больше, чем если будете просто читать.

CROSS JOIN (перекрестное объединение)

Самое простое объединение, которое мы можем сделать, это CROSS JOIN (перекрестное объединение) или «декартово произведение».

При этом объединении мы берем каждую строку одной таблицы и соединяем ее с каждой строкой другой таблицы.

Каждое значение из первого списка соединено с каждым значением второго списка.

Давайте перепишем этот пример в виде SQL-запроса.

Для начала создадим две очень похожих таблицы и внесем в них данные:

Наши таблицы letters и numbers имеют по одному столбцу с простыми текстовыми полями.

Теперь давайте объединим эти таблицы, используя CROSS JOIN:

Хотя этот пример часто упоминается как чисто учебный, и для него есть практическое применение: покрытие диапазона дат.

CROSS JOIN с диапазонами дат

Хороший вариант использования CROSS JOIN — брать каждую строку таблицы и объединять ее с каждым днем из диапазона дат.

Скажем, вы создаете приложение, которое должно отслеживать ежедневную рутину (чистка зубов, завтрак, душ).

Если вы хотите генерировать запись для каждой задачи за каждый день прошлой недели, вы можете использовать CROSS JOIN с диапазоном дат.

Чтобы создать диапазон дат, мы можем воспользоваться функцией generate_series:

Функция generate_series принимает три параметра.

Второй параметр — текущая дата ( CURRENT_DATE ).

Третий параметр — шаг. То есть, на сколько мы хотим инкрементировать значение. Поскольку это ежедневные задачи, мы устанавливаем в качестве интервала один день ( INTERVAL ‘1 day’ ).

Все вместе генерирует серию дат, начиная с даты пятидневной давности и заканчивая сегодняшним днем, по дню за раз.

Результат запроса за последние пять дней плюс сегодняшний:

Возвращаемся к нашему примеру с ежедневными задачами. Давайте создадим простую таблицу, в которой будут содержаться наши задачи (и добавим несколько):

В нашей таблице tasks есть только один столбец — name — в который мы добавили несколько задач.

Теперь давайте осуществим перекрестное объединение наших задач с запросом на генерацию дат:

(Поскольку наш запрос для генерации дат по сути не является таблицей, мы просто написали его в виде подзапроса).

В результате мы получаем название задачи и день. Выглядит это следующим образом:

Как и ожидалось, мы получили по строке для каждой задачи на каждый день из нашего диапазона дат.

CROSS JOIN это простейшее объединение. Дальнейшие примеры потребуют более «жизненной» настройки таблиц.

Создание таблиц directors и movies

Чтобы проиллюстрировать следующие виды объединений, мы воспользуемся примером с фильмами (movies) и режиссерами (movie directors).

Каждый фильм имеет режиссера, но это не является обязательным условием. Может быть ситуация, когда фильм уже анонсировали, но режиссер еще не выбран.

В нашей таблице directors будут храниться имена всех режиссеров, а в таблице movies — названия фильмов, а также отсылка к режиссеру (если он известен).

Давайте создадим эти таблицы и внесем в них необходимые данные:

У нас есть пять режиссеров и пять фильмов, причем для трех фильмов указаны режиссеры. У режиссера с ID 1 есть два фильма, а у режиссера с ID 2 — один фильм.

FULL OUTER JOIN (полное внешнее объединение)

Теперь у нас есть данные, с которыми можно работать, так что переходим к следующему виду объединения — FULL OUTER JOIN.

FULL OUTER JOIN похоже на CROSS JOIN, но имеет важные отличия.

Первое отличие состоит в том, что для FULL OUTER JOIN требуется условие объединения.

Это условие определяет, как именно связаны строки разных таблиц и по какому критерию они должны объединяться.

Вот как это выглядит в коде:

Наш результат выглядит, как некое странное декартово произведение:

Сначала идут несколько строк с фильмами, для которых указаны режиссеры: здесь наше условие явно соблюдается.

Но после мы видим оставшиеся строки из каждой таблицы, но со значениями NULL в тех местах, где в другой таблице не нашлось совпадений.

Примечание: если вы не знакомы со значениями NULL, объяснение можно почитать здесь.

Здесь мы также видим второе различие между перекрестным и полным внешним объединением. FULL OUTER JOIN соединяет одну строку первой таблицы с определенной строкой второй таблицы, а при CROSS JOIN каждая строка одной таблицы соединяется с каждой строкой другой.

INNER JOIN

Следующий вид объединения — внутреннее, INNER JOIN. Внутреннее объединение является наиболее используемым.

INNER JOIN возвращает только те строки, где соблюдается условие объединения.

Если брать наш пример с таблицами movies и directors, внутреннее объединение вернет только те записи, где у фильма есть указанный режиссер.

Синтаксис практически тот же:

В результирующую выборку попали только фильмы с режиссерами:

Поскольку внутреннее объединение дает нам только те строки, для которых соблюдается условие объединения, порядок указания таблиц не имеет значения.

Если мы поменяем местами названия таблиц в запросе, результат будет тот же:

Единственное отличие в том, что поскольку мы выбрали все столбцы ( SELECT * ) и сначала указали таблицу directors, то в результате первыми будут идти данные из этой таблицы, а дальше — из таблицы movies. Но данные, попавшие в выборку, те же.

Это полезное свойство операции внутреннего объединения: не у всех видов объединений оно есть.

Конец первой части. Читайте во второй части:

Источник

Оператор языка SQL JOIN предназначен для соединения двух или более таблиц базы данных по совпадающему условию. Этот оператор существует только в реляционных базах данных. Именно благодаря JOIN реляционные базы данных обладают такой мощной функциональностью, которая позволяет вести не только хранение данных, но и их, хотя бы простейший, анализ с помощью запросов. Разберём основные нюансы написания SQL-запросов с оператором JOIN, которые являются общими для всех СУБД (систем управления базами данных). Для соединения двух таблиц оператор SQL JOIN имеет следующий синтаксис:

После одного или нескольких звеньев с оператором JOIN может следовать необязательная секция WHERE или HAVING, в которой, также, как в простом SELECT-запросе, задаётся условие выборки. Общим для всех СУБД является то, что в этой конструкции вместо JOIN может быть указано INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, CROSS JOIN (или, как вариант, запятая).

INNER JOIN (внутреннее соединение)

Запрос с оператором INNER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON.

Sql join что это. join inner. Sql join что это фото. Sql join что это-join inner. картинка Sql join что это. картинка join inner

Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке .

Таблицы этой базы данных с заполненными данными имеют следующий вид.

CatnumbCat_namePrice
10Стройматериалы105,00
505Недвижимость210,00
205Транспорт160,00
30Мебель77,00
45Техника65,00
Part_IDPartCat
1Квартиры505
2Автомашины205
3Доски10
4Шкафы30
5Книги160

Результатом выполнения запроса будет следующая таблица:

PartCatPrice
Квартиры505210,00
Автомашины205160,00
Доски10105,00
Шкафы3077,00

В результирующей таблице нет Книг, так как эта запись ссылается на категорию, которой нет в таблице Categories, и Техники, так как эта запись имеет внешний ключ в таблице Categories, на который нет ссылки в таблице Parts.

В ряде случаев при соединениях таблиц составить менее громоздкие запросы можно с помощью предиката EXISTS и без использования JOIN.

Написать запросы SQL с JOIN самостоятельно, а затем посмотреть решения

Sql join что это. theatre having. Sql join что это фото. Sql join что это-theatre having. картинка Sql join что это. картинка theatre having

Пример 2. Определить самого востребованного актёра за последние 5 лет.

Оператор JOIN использовать 2 раза. Использовать COUNT(), CURDATE(), LIMIT 1.

Пример 3. Вывести список актеров, которые в одном спектакле играют более одной роли, и количество их ролей.

Оператор JOIN использовать 1 раз. Использовать HAVING, GROUP BY.

Подсказка. Оператор HAVING применяется к числу ролей, подсчитанных агрегатной функцией COUNT.

LEFT OUTER JOIN (левое внешнее соединение)

Запрос с оператором LEFT OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из первой по порядку (левой) таблицы, даже если они не соответствуют условию. У записей левой таблицы, которые не соответствуют условию, значение столбца из правой таблицы будет NULL (неопределённым).

Sql join что это. join left. Sql join что это фото. Sql join что это-join left. картинка Sql join что это. картинка join left

Для получения результирующей таблицы, в которой данные из двух таблиц полностью пересекаются по условию и дополняются всеми данными из таблицы Parts, которые не соответствуют условию, пишем следующий запрос:

Результатом выполнения запроса будет следующая таблица:

PartCatPrice
Квартиры505210,00
Автомашины205160,00
Доски10105,00
Шкафы3077,00
Книги160NULL

RIGHT OUTER JOIN (правое внешнее соединение)

Запрос с оператором RIGHT OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из второй по порядку (правой) таблицы, даже если они не соответствуют условию. У записей правой таблицы, которые не соответствуют условию, значение столбца из левой таблицы будет NULL (неопределённым).

Sql join что это. join right. Sql join что это фото. Sql join что это-join right. картинка Sql join что это. картинка join right

Для получения результирующей таблицы, в которой данные из двух таблиц полностью пересекаются по условию и дополняются всеми данными из таблицы Categories, которые не соответствуют условию, пишем следующий запрос:

Результатом выполнения запроса будет следующая таблица:

PartCatPrice
Квартиры505210,00
Автомашины205160,00
Доски10105,00
Шкафы3077,00
NULL4565,00

FULL OUTER JOIN (полное внешнее соединение)

Запрос с оператором FULL OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из первой (левой) и второй (правой) таблиц, даже если они не соответствуют условию. У записей, которые не соответствуют условию, значение столбцов из другой таблицы будет NULL (неопределённым).

Sql join что это. join full. Sql join что это фото. Sql join что это-join full. картинка Sql join что это. картинка join full

Для получения результирующей таблицы, в которой данные из двух таблиц полностью пересекаются по условию и дополняются всеми данными как из таблицы Parts, так и из таблицы Categories, которые не соответствуют условию, пишем следующий запрос:

Результатом выполнения запроса будет следующая таблица:

PartCatPrice
Квартиры505210,00
Автомашины205160,00
Доски10105,00
Шкафы3077,00
Книги160NULL
NULL4565,00

Псевдонимы соединяемых таблиц

Пример 7. Переписать запрос из примера 1 с использованием псевдонимов соединяемых таблиц.

Запрос будет следующим:

Запрос вернёт то же самое, что и запрос в примере 1, но он гораздо компактнее.

JOIN и соединение более двух таблиц

A_IdPart_IDDate_startDate_endText
211‘2018-02-11’‘2018-04-20’«Продаю. «
221‘2018-02-11’‘2018-05-12’«Продаю. «
.....
271‘2018-02-11’‘2018-04-02’«Продаю. «
282‘2018-02-11’‘2018-04-21’«Продаю. «
292‘2018-02-11’‘2018-04-02’«Продаю. «
303‘2018-02-11’‘2018-04-22’«Продаю. «
314‘2018-02-11’‘2018-05-02’«Продаю. «
324‘2018-02-11’‘2018-04-13’«Продаю. «
333‘2018-02-11’‘2018-04-12’«Продаю. «
344‘2018-02-11’‘2018-04-23’«Продаю. «

Запрос будет следующим:

Cat_name
Недвижимость
Транспорт

CROSS JOIN (перекрестное соединение)

Запрос будет следующим:

Запрос вернёт таблицу из 5 * 5 = 25 строк, фрагмент которой приведён ниже:

CatnumbCat_namePricePart_IDPartCat
10Стройматериалы105,001Квартиры505
10Стройматериалы105,002Автомашины205
10Стройматериалы105,003Доски10
10Стройматериалы105,004Шкафы30
10Стройматериалы105,005Книги160
......
45Техника65,001Квартиры505
45Техника65,002Автомашины205
45Техника65,003Доски10
45Техника65,004Шкафы30
45Техника65,005Книги160

Как видно из примера, если результат такого запроса и имеет какую-либо ценность, то это, возможно, наглядная ценность в некоторых случаях, когда не требуется вывести структурированную информацию, тем более, даже самую простейшую аналитическую выборку. Кстати, можно указать выводимые столбцы из каждой таблицы, но и тогда информационная ценность такого запроса не повысится.

Но для CROSS JOIN можно задать условие соединения! Результат будет совсем иным. При использовании оператора «запятая» вместо явного указания CROSS JOIN условие соединения задаётся не словом ON, а словом WHERE.

Запрос будет следующим:

Запрос вернёт то же самое, что и запрос в примере 1:

PartCatPrice
Квартиры505210,00
Автомашины205160,00
Доски10105,00
Шкафы3077,00

Источник

Осмысляем работу джойнов в SQL: от реляционной алгебры до наглядных картинок

Выбираем, какие фильмы посмотреть, с помощью соединения данных в SQL.

Sql join что это. 88a7dcb1df1c0cc0498b6bd55137dfa0. Sql join что это фото. Sql join что это-88a7dcb1df1c0cc0498b6bd55137dfa0. картинка Sql join что это. картинка 88a7dcb1df1c0cc0498b6bd55137dfa0

Sql join что это. 4e437a86bc5bcb0937bffed21f687339. Sql join что это фото. Sql join что это-4e437a86bc5bcb0937bffed21f687339. картинка Sql join что это. картинка 4e437a86bc5bcb0937bffed21f687339

Опять эта проблема — выбрать кино на вечер. Благодаря стриминговым сервисам доступны едва ли не все фильмы мира: это бесконечное полотно с постерами и фильтры, фильтры, фильтры…

Sql join что это. 13423814042021 c3d4b76cd89b05f2c8e5da53f69c6d45806e9160. Sql join что это фото. Sql join что это-13423814042021 c3d4b76cd89b05f2c8e5da53f69c6d45806e9160. картинка Sql join что это. картинка 13423814042021 c3d4b76cd89b05f2c8e5da53f69c6d45806e9160

МОЗГ: Поставлю-ка я фильтр по стране: пусть будет Дания, и добавлю ограничение по жанру — триллер… Ну вот — другое дело, относительно небольшой список.

— Мозг, а знаешь почему? Да потому что здесь только фильмы, которые сняты в Дании И помечены как триллеры.

— Да не знаю я, как задать такие критерии в этом сервисе. Вот если бы можно было писать на SQL — тут бы решение нашлось для любой комбинации признаков.

— Легко! Ещё и картинки будут. У меня и база фильмов уже спарсена — тренируйся не хочу.

Sql join что это. 13404114042021 bf4ba0be2db1e79d59dc4eb20a68c1fa8285f50a. Sql join что это фото. Sql join что это-13404114042021 bf4ba0be2db1e79d59dc4eb20a68c1fa8285f50a. картинка Sql join что это. картинка 13404114042021 bf4ba0be2db1e79d59dc4eb20a68c1fa8285f50a

Фулстек-разработчик. Любимый стек: Java + Angular, но в хорошей компании готова писать хоть на языке Ада.

Договоримся об обозначениях

Назовём множество датских фильмов — D, а множество триллеров — T. У каждого фильма будет уникальный номер, он же ключ. Раз ключ — пусть зовётся Key.

Заодно вспомним, как на SQL пишется простой запрос для связывания данных из двух таблиц:

INNER JOIN

Если не уточнить тип соединения ( JOIN), то по умолчанию применяется INNER JOIN — как раз тот вариант, который сработал в нашем кинофильтре. Это он выбирает и триллеры, и датские фильмы одновременно.

Источник

Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite

Базы данных

SQL оператор JOINS

В этом учебном материале вы узнаете, как использовать SQL JOINS с синтаксисом и примерами.

Описание

SQL JOINS используются для извлечения данных из нескольких таблиц. SQL JOIN выполняется всякий раз, когда две или более таблицы перечислены в операторе SQL.

Существует 4 различных типа соединений SQL:

Итак, давайте обсудим синтаксис SQL JOIN, рассмотрим наглядные иллюстрации SQL JOINS и рассмотрим несколько примеров.

SQL INNER JOIN (простое соединение)

Скорее всего, вы уже писали SQL запрос, который использует SQL INNER JOIN. Это наиболее распространенный тип соединения SQL. INNER JOIN возвращает все строки из нескольких таблиц, где выполняется условие соединения.

Синтаксис

Синтаксис INNER JOIN в SQL:

Рисунок.

Пример

Давайте рассмотрим пример использования INNER JOIN в запросе.

В этом примере у нас есть таблица customer и следующими данными:

customer_idfirst_namelast_namefavorite_website
4000JustinBiebergoogle.com
5000SelenaGomezbing.com
6000MilaKunisyahoo.com
7000TomCruiseoracle.com
8000JohnnyDeppNULL
9000RussellCrowegoogle.com

И таблица orders со следующими данными:

order_idcustomer_idorder_date
170002019/06/18
250002019/06/18
380002019/06/19
440002019/06/20
5NULL2019/07/01

Выполним следующий SQL оператор:

Будет выбрано 4 записи. Вот результаты, которые вы должны получить:

customer_idorder_idorder_date
400042019/06/20
500022019/06/18
700012019/06/18
800032019/06/19

SQL LEFT OUTER JOIN

Другой тип соединения называется LEFT OUTER JOIN. Этот тип соединения возвращает все строки из таблиц с левосторонним соединением, указанным в условии ON, и только те строки из другой таблицы, где объединяемые поля равны (выполняется условие соединения).

Синтаксис

Синтаксис для LEFT OUTER JOIN в SQL:

В некоторых базах данных ключевое слово OUTER опущено и записывается просто как LEFT JOIN.

Рисунок

Пример

Теперь давайте рассмотрим пример, который показывает, как использовать LEFT OUTER JOIN в операторе SELECT.

customer_idfirst_namelast_namefavorite_website
4000JustinBiebergoogle.com
5000SelenaGomezbing.com
6000MilaKunisyahoo.com
7000TomCruiseoracle.com
8000JohnnyDeppNULL
9000RussellCrowegoogle.com

И таблицу orders со следующими данными:

order_idcustomer_idorder_date
170002019/06/18
250002019/06/18
380002019/06/19
440002019/06/20
5NULL2019/07/01

Введите следующий SQL оператор:

Будет выбрано 6 записей. Вот результаты, которые вы получите:

customer_idorder_idorder_date
400042019/06/20
500022019/06/18
6000NULLNULL
700012019/06/18
800032019/06/19
9000NULLNULL

SQL RIGHT OUTER JOIN JOIN

Другой тип соединения называется SQL RIGHT OUTER JOIN. Этот тип соединения возвращает все строки из таблиц с правосторонним соединением, указанным в условии ON, и только те строки из другой таблицы, где объединяемые поля равны (выполняется условие соединения).

Синтаксис

Синтаксис для RIGHT OUTER JOIN в SQL:

В некоторых базах данных ключевое слово OUTER опущено и записывается просто как RIGHT JOIN.

Рисунок

На этом рисунке SQL RIGHT OUTER JOIN возвращает затененную область:

Пример

Теперь давайте рассмотрим пример, который показывает, как использовать RIGHT OUTER JOIN в операторе SELECT.

customer_idfirst_namelast_namefavorite_website
4000JustinBiebergoogle.com
5000SelenaGomezbing.com
6000MilaKunisyahoo.com
7000TomCruiseoracle.com
8000JohnnyDeppNULL
9000RussellCrowegoogle.com

И таблицу orders со следующими данными:

order_idcustomer_idorder_date
170002019/06/18
250002019/06/18
380002019/06/19
440002019/06/20
5NULL2019/07/01

Введите следующий SQL оператор:

Будет выбрано 5 записей. Вот результаты, которые вы должны получить:

customer_idorder_idorder_date
NULL52019/07/01
400042019/06/20
500022019/06/18
700012019/06/18
800032019/06/19

SQL FULL OUTER JOIN

Другой тип объединения называется SQL FULL OUTER JOIN. Этот тип объединения возвращает все строки из LEFT таблицы и RIGHT таблицы со значениями NULL в месте, где условие соединения не выполняется.

Синтаксис

Синтаксис для SQL FULL OUTER JOIN:

В некоторых базах данных ключевое слово OUTER опускается и записывается просто как FULL JOIN.

Рисунок

Пример

Давайте рассмотрим пример, который показывает, как использовать FULL OUTER JOIN в операторе SELECT.

customer_idfirst_namelast_namefavorite_website
4000JustinBiebergoogle.com
5000SelenaGomezbing.com
6000MilaKunisyahoo.com
7000TomCruiseoracle.com
8000JohnnyDeppNULL
9000RussellCrowegoogle.com

И таблицу orders со следующими данными:

order_idcustomer_idorder_date
170002019/06/18
250002019/06/18
380002019/06/19
440002019/06/20
5NULL2019/07/01

Введите следующий SQL оператор:
SELECT customers.customer_id,
orders.order_id,
orders.order_date
FROM customers
FULL OUTER JOIN orders
ON customers.customer_id = orders.customer_id
ORDER BY customers.customer_id;

Будет выбрано 7 записей. Вот результаты, которые вы получите:

customer_idorder_idorder_date
NULL52019/07/01
400042019/06/20
500022019/06/18
6000NULLNULL
700012019/06/18
800032019/06/19
9000NULLNULL

Как видите, строки, где customer_id равен 6000 и 9000, будут включены, но поля order_id и order_date для этих записей содержат значение NULL. Строка, где order_id равен 5, также будет включена, но поле customer_id для этой записи имеет значение NULL.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *