Я много лет страстно увлечен базами данных и программированием на языке 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