Найти тему
Идеальный блокчейн

SQL. Практика баз данных для хипстеров. Story #5

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

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

Содержание беседы #5:

Тема 2. Язык структурированных запросов

Раздел 2.1 Понятие Стандарта ANSI-SQL

Пункт 2.1.3 Дополнительные операторы (Case When…Then…Else…End, Union)

Оператор ветвления Case.

Позволю себе лирическое отступление. Ребята, в мире компьютерных технологий всё просто, когда знаешь основы. Все компьютерные системы и механизмы в основе своём имеют всего два принципа: соглашения и умолчания. А все языки программирования в основе имеют три оператора: присвоения, цикла и ветвления.

SQL не исключение. Присвоение здесь явное, цикл на уровне запроса обеспечивается перебором всех строк таблиц. Ветвление на уровне T-SQL обеспечивает пресловутый "IF", а внутри самого запроса - оператором "Case".

В программировании часто возникает ситуация, когда в некоторой точке ситуация может начать развиваться по разным сценариям. По-русски, это выглядит так:

Если <логическое условие> То … Иначе …

В SQL-запросе такая ситуация возникает реже, но всё-таки возникает.

Если решение касается глобальных вопросов, выходящих за рамки одного запроса: выполнять ли один запрос или другой; выполнять ли вообще запрос? Это пишется на языке T-SQL.

А вот если вопрос стоит так: сделать ли проверку по первому полю или по второму, вывести ли одно значение или другое? Это работа для оператора Case.

Оператор состоит из 5 последовательных слов. Есть варианты его использования, но при базовом использовании лучше запомнить, что писать нужно все 5 слов:

Case When <логическое условие> Then Значение1 Else Значение2 End

Пример использования:

Case When Age < 18 Then ‘Ребенок’ Else ‘Взрослый’ End

Оператор может быть использован в любом разделе, потому что это не логическое условие! Результат оператора Case – не True/False/Unknown, а конкретное значение (число, дата, текст, возможно Null).

Привожу примеры использования оператора в разных разделах запроса:

1) Select *, Case When Age < 18 Then ‘Ребенок’ Else ‘Взрослый’ End From…

2) Задача: «Для аудиторской проверки найти все договора по аренде помещений, где город, в котором находится помещение, является городом, где клиент прописан. Сделать поблажку для сотрудников – их договора на такое строго соответствие можно не проверять».

Для такой непросто звучащей задачи есть простое решение с помощью оператора Case:

… Where Contracts.Town = Case When Contracts.TableNumber <> ‘’
Then Contracts.Town
Else Clients.TownRegistration End

3) Зададим гибкую сортировку:

… Order By 1, Case When Age < 18 Then 2 Else 3 End

4) Использование во From носит теоретический характер и обычно не применяется, хотя его можно использовать в условиях после Join … On …

5) Внутри агрегатов на «продвинутом» уровне использования SQL.

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

Select Sum(PriceSum) From Tovar Where PriceSum >= 50
Select Sum(Case When PriceSum < 50 Then 0 Else PriceSum End)…

Итог: так же как подзапрос для нас должен быть черным ящиком, возвращающим набор строк (от 0 до бесконечности), но о структуре которого мы не думаем, так и оператор Case – черный ящик, но возвращающий одно и только одно значение (в частном случае - Null).

Оператор объединения запросов Union.

Иногда могут возникнуть следующие потребности. Необходимо объединить результат вывода двух или более:

1. … разных по виду запросов.

2. … одинаковых по виду, но берущих значения из разных таблиц запросов.

Задача: составить список всех документов, информация о которых есть в базе (например, для составления номенклатуры).

Select ‘Договор’ as ‘Тип’, Number From Contracts
Union All
Select ‘Справка’, SprNum From Spravki

Важные правила использования оператора Union:

· Количество столбцов во всех запросах должно быть одинаково.

· Типы данных каждых соответствующих своему порядковому номеру столбцов должны быть равны (а точнее – быть схожи).

· Итоговые названия столбцов объединенного запроса получаются равными названиям первого запроса. Если у поля нет названия (оно вычислимое), то его обязательно необходимо задать.

· Если опция All указана – это означает «взять все полученные строки без устранения дубликатов». Если же в нашем примере написать просто Union, и не указать тип документа первым полем, и попадется договор и справка с одинаковым номером, то строки будет не две, а одна.

Среди программистов есть правило: если не знаешь использовать Union или Union All, то используй Union All.

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

Спасибо, что дочитали до конца! Любите друг друга... и базы данных)

Автор: Щукин Андрей (vk.com/faustonly), Санкт-Петербург. Дата публикации: 21.04.2018