В рамках данной статьи я расскажу вам об условной операторе CASE, без которого учет данных в ряде задач превратился бы в нагромождения кусков кода, а так же о том, как его применять в SQL-запросах.
Как бы хорошо вы не спроектировали вашу базу данных, всегда будут возникать задачи, где без условных операторов не обойтись. Например, вместо огромных цифр получить словесное описание, или же в зависимости от наличия (отсутствия) данных добавить в строку дополнительные символы, или как более сложный пример - в зависимости от разных нюансов отнести запись к той или иной группе. Ситуаций масса.
В принципе, у данного оператора существует, как минимум, две формы в разных базах данных. Первый вариант напоминает обычный switch из любого языка программирования. Второй зависит от логических выражений.
Однако, в рамках данной статьи я рассмотрю именно второй вариант, так как у него не возникает проблем с ситуациями вроде CASE WHEN NULL (null в рамках БД не является конкретным значением, поэтому его нельзя использовать в switch подобном операторе). Кроме того, в обыденной жизни чаще всего встречаются задачи именно для второго варианта - вычисление через логические выражения. Поэтому лучше сразу научиться и продолжать использовать именно его.
Обычно, он описывается так (синтаксис может меняться в зависимости от БД):
CASE WHEN bool_expression1 THEN value1 ..... WHEN bool_expressionN THEN valueN ELSE valueElse END
bool_expressionX - это логическое условие
valueX - это то значение, которое будет подставлено, если выполнено соответствующее логическое условие
valueElse - это значение, которое будет подставлено, если ранее не выполнилось ни одно условие.
После такой небольшой справки, перейдем к практике.
Примечание : Кстати, стоит знать, что обычно этот оператор можно применять не только в select, но и в любом месте, где можно использовать поля. Например, при join таблиц или же даже фильтрации (having) при группировке (group by) .
Чтобы лучше понять условный оператор CASE...WHEN...THEN, представим себе небольшую задачу. Допустим, у вас есть таблица с данными о клиентах и их суммарном количестве покупок. И стоит задача динамически формировать скидку. Можно было бы, конечно, вручную выставлять скидку. Но, она у вас пороговая, причем пороги жестко зашиты (что-то вроде - сумма больше 1000 получи скидку в 2%, а больше 5000 - получи 5%) и вы бы хотели этот процесс автоматизировать, чтобы не пришлось искать ошибки и каждый раз копаться в базе данных (накопил клиент нужную сумму - скидка автоматически появилась).
Возьмем условную таблицу client с тремя клиентами. Для примера их будет вполне достаточно.
Теперь, зададим несколько условий автоматического предоставления скидки исходя из задачи. При этом считаем, что клиенту в любом случае предоставляется максимальная скидка.
1. Сумма от 1000 - скидка 2%
2. Сумма от 5000 - скидка 5%
3. Сумма от 10000 - скидка 8%
4. Количество заказов от 10 - скидка 7%
5. Количество заказов от 20 - скидка 8%
Как видите, скидка зависит от двух факторов от суммы и от количества. Теперь, попробуем из них создать условия исходя от скидки, то есть правила наоборот, чтобы их можно было использовать в sql-запросе. Получим следующее:
1. 2% - Сумма от 1000 до 4999 и количество заказов меньше 10.
2. 5% - Сумма от 5000 до 9999 и количество заказов меньше 10.
3. 7% - Количество заказов от 10 до 19 и сумма меньше 10000
4. 8% - Количество от 20 или сумма от 10000
Теперь, осталось только записать. Получим следующий sql-запрос
Выводим имя и остальные данные select name, order_count, total_sum, -- А теперь выводим скидку CASE -- Первое правило 2% WHEN c.total_sum >= 1000 and c.total_sum <= 4999 and c.order_count < 10 THEN 2 -- Второе правило 5% WHEN c.total_sum >= 5000 and c.total_sum <= 9999 and c.order_count < 10 THEN 5 -- Третье правило 7% WHEN c.total_sum < 10000 and c.order_count >= 10 and c.order_count <= 19 THEN 5 -- Четвертое правило 8% WHEN c.total_sum >= 10000 or c.order_count >= 20 THEN 5 -- Ни одно правило не выполнено, значит скидка 0. ELSE 0 END as discount from client c
В результате выполнения получим следующую таблицу:
Как видите, два клиента получили скидку 8 процентов, а один клиент получил скидку в 2 процента. При этом с каждым заказом процент будет автоматически вычисляться и вам ничего не нужно будет корректировать. К примеру, если у Петя сумма увеличится до 5000, то его скидка автоматически поднимется до 5% (как минимум, так как есть еще число заказов).
It is difficult to explain the syntax for the SQL Server WHERE clause, so let"s look at some examples.
We"ll start by looking at how to use the WHERE clause with only a single condition.
SELECT * FROM employees WHERE first_name = "Jane";
In this SQL Server WHERE clause example, we"ve used the WHERE clause to filter our results from the employees table. The SELECT statement above would return all rows from the employees table where the first_name is "Jane". Because the * is used in the SELECT, all fields from the employees table would appear in the result set.
Let"s look at how to use the WHERE clause with the AND condition.
SELECT * FROM employees WHERE last_name = "Anderson" AND employee_id >= 3000;
This SQL Server WHERE clause example uses the WHERE clause to define multiple conditions. In this case, this SELECT statement uses the AND condition to return all employees that have a last_name of "Anderson" and the employee_id is greater than or equal to 3000.
Let"s look at how to use the WHERE clause with the OR condition.
SELECT employee_id, last_name, first_name FROM employees WHERE last_name = "Johnson" OR first_name = "Danielle";
This SQL Server WHERE clause example uses the WHERE clause to define multiple conditions, but instead of using the AND condition , it uses the OR condition . In this case, this SELECT statement would return all employee_id , last_name , and first_name values from the employees table where the last_name is "Johnson" or the first_name is "Danielle".
Let"s look at how to use the WHERE clause when we combine the AND & OR conditions in a single SQL statement.
SELECT * FROM employees WHERE (state = "California" AND last_name = "Smith") OR (employee_id = 82);
This SQL Server WHERE clause example uses the WHERE clause to define multiple conditions, but it combines the AND condition and the OR condition . This example would return all employees that reside in the state of "California" and whose last_name is "Smith" as well as all employees whose employee_id is equal to 82.
The parentheses determine the order that the AND and OR conditions are evaluated. Just like you learned in the order of operations in Math class!
Let"s look at how to use the WHERE clause when we join multiple tables together.
SELECT employees.employee_id, contacts.last_name FROM employees INNER JOIN contacts ON employees.employee_id = contacts.contact_id WHERE employees.first_name = "Sarah";
This SQL Server WHERE clause example uses the WHERE clause to join multiple tables together in a single SELECT statement. This SELECT statement would return all rows where the first_name in the employees table is "Sarah". And the employee s and contacts tables are joined on the employee_id from the employees table and the contact_id from the contacts table.
В реализациях языка SQL может быть выполнено неявное преобразование типов. Так, например, в T-SQL при сравнении или комбинировании значений типов smallint и int , данные типа smallint неявно преобразуются к типу int . Подробно о явном и неявном преобразовании типов в MS SQL Server можно прочитать в BOL.
Пример.
Вывести среднюю цену ПК-блокнотов с предваряющим текстом "средняя цена = ".
Попытка выполнить запрос
Т.е. мы использовали неявное преобразование целочисленного аргумента к точному числовому типу (EXACT NUMERIC), умножив его на вещественную единицу, после чего применили явное приведения типа результата агрегатной функции.
Аналогичные преобразования типа можно выполнить с помощью функции CONVERT :
Пусть требуется вывести список всех моделей ПК с указанием их цены. При этом если модель отсутствует в продаже (нет в таблице РС), то вместо цены вывести текст: "Нет в наличии".
Список всех моделей ПК с ценами можно получить с помощью запроса:
SELECT DISTINCT product.model, price FROM product LEFT JOIN pc c
ON product.model=c.model WHERE product.type="pc"; |
model | price |
1121 | 850 |
1232 | 350 |
1232 | 400 |
1232 | 600 |
1233 | 600 |
1233 | 950 |
1233 | 980 |
1260 | 350 |
2111 | NULL |
2112 | NULL |
model | price |
1121 | 850 |
1232 | 350 |
1232 | 400 |
1232 | 600 |
1233 | 600 |
1233 | 950 |
1233 | 980 |
1260 | 350 |
2111 | Нет в наличии |
2112 | Нет в наличии |
Оператор CASE может быть использован в одной из двух синтаксических форм записи:
1-я форма
CASE <проверяемое выражение>
WHEN <сравниваемое выражение 1>
THEN <возвращаемое значение 1>
…
WHEN <сравниваемое выражение N>
THEN <возвращаемое значение N>
END
2-я форма
CASE
WHEN <предикат 1>
THEN <возвращаемое значение 1>
…
WHEN <предикат N>
THEN <возвращаемое значение N>
END
Все предложения WHEN
должны иметь одинаковую синтаксическую форму, т.е. нельзя смешивать первую и вторую формы.
При использовании первой синтаксической формы условие WHEN
удовлетворяется,
как только значение проверяемого выражения
станет равным значению выражения,
указанного в предложении WHEN
. При использовании второй синтаксической формы условие WHEN
удовлетворяется, как только предикат
принимает значение TRUE.
При удовлетворении условия оператор CASE
возвращает значение, указанное в соответствующем предложении THEN
.
Если ни одно из условий WHEN
не выполнилось, то будет использовано значение, указанное в предложении ELSE
.
При отсутствии ELSE
, будет возвращено NULL-значение. Если удовлетворены несколько условий, то будет возвращено
значение предложения THEN
первого из них.
В приведенном выше примере была использована вторая форма оператора CASE
.
Заметим, что для проверки на NULL стандарт предлагает более короткую форму оператора
- COALESCE
. Этот оператор имеет произвольное число параметров и возвращает
значение первого, отличного от NULL. Для двух параметров оператор COALESCE(A, B)
эквивалентен следующему оператору CASE
:
CASE WHEN A IS NOT NULL THEN A ELSE B END
Решение рассмотренного выше примера при использовании оператора COALESCE можно переписать следующим образом:
Использование первой синтаксической формы оператора CASE можно продемонстрировать на следующем примере : Вывести все имеющиеся модели ПК с указанием цены. Отметить самые дорогие и самые дешевые модели.
SELECT DISTINCT model, price,
CASE price WHEN (SELECT MAX(price) FROM pc) THEN "Самый дорогой" WHEN (SELECT MIN(price) FROM pc) THEN "Самый дешевый" ELSE "Средняя цена" END comment FROM pc ORDER BY price; |
В результате выполнения запроса получим
model | price | comment |
1232 | 350 | Самый дешевый |
1260 | 350 | Самый дешевый |
1232 | 400 | Средняя цена |
1233 | 400 | Средняя цена |
1233 | 600 | Средняя цена |
1121 | 850 | Средняя цена |
1233 | 950 | Средняя цена |
1233 | 980 | Самый дорогой |
Одним из самых распространенных языков программирования для работы с базами данных считается SQL. Конструкции языка позволяют не только создать базу, но и проводить с ней разнообразные манипуляции на изменение данных или их выборку.
Для выбора данных с базы используется конструкция Select [набор данных] from [имя таблицы]. Как показывает опыт, в 80 % случаев использования запросов на выборку данных нужно применять разнообразные условия — параметры. Для этого в язык, как дополнение к запросу, его усложнение, введено условие SQL-Where.
Довольно часто программисту необходимо отобрать, в основном для предоставления отчета, данные, хранимые в базе. Для этого может быть недостаточно построить простой запрос на выборку. Как правило, необходимо еще учитывать разнообразные условия, параметры выборки, которых может быть довольно много, или проверять. входят ли данные в очерченный диапазон или находятся в определенной таблице.
Конструкция SQL-Where может быть использована для задания условий выборки данных или для проверки вхождения данных в выборку или стороннюю таблицу.
Если нужно задать определенные параметры для выбора с базы отчетных данных, синтаксис конструкции SQL-Where можно организовать довольно просто. Для этого можно пользоваться следующими правилами:
Нужно простроить стандартный запрос, с помощью конструкции Select * from.
Определить с помощью ключевой конструкции Join, с каких таблиц будет делаться выбор.
С помощью конструкции Where задать перечень параметров для выборки.
Такого рода запросы довольно просты в построении и не вызывают трудностей даже у новичков.
Если программисту поставлена задача не только выбрать из таблицы данные по условию, но и проверить их вхождение в одну или несколько таблиц другого плана, конструкция SQL-Where будет незаменима.
С помощью синтаксиса этой конструкции можно построить те же условия, но с вложенными запросами, которые будут проверять вхождение выбираемых строк в набор сторонних таблиц базы данных.
Как правило, для таких целей формируется временная таблица, в которую записывается весь необходимый, для проверки вхождения набор данных.
Сейчас будут приведены примеры Для начал представим, что есть две таблицы с данными — Tovar и TovarAmount. В первой имеются названия продаваемого товара, цена, дата продажи и клиент, который приобрел товар. Во второй указано наличие товара, а если точнее, какой есть в наличии.
Примером запроса с параметром, который укажет все товары, проданные за определенное количество дней, будет конструкция следующего характера:
Select * from Tovar
Where T_Date >= ‘12/01/2016’ and T_Date<= ‘’12/07/1016 and T_PriceOut >0
Такого плана запрос вернет список товаров, данных с таблицы, которые были проданы за первые семь дней декабря, на что указывает одно из условий выборки: T_PriceOut >0.
Если же рассмотреть условие вывода товаров, которые есть в наличии, то конструкция будет такого плана:
Select * from Tovar
Where T_Tovar in (select TA_Tovar where TA_ Amount >0)
Вложенных условий в Where может быть много, но стоит упомянуть, что чем больше условий накладывается, тем дольше будет работать запрос. Именно это стало причиной использования временных таблиц. Намного быстрее сформировать несколько таких, а потом сравнить данные в них, чем строить условие с несколькими уровнями проверки данных.
При выборке записей из таблицы практически всегда требуется задавать определённые условия, по которым мы определяем, какие записи нам нужны, а какие - нет. И именно эти условия можно задавать с помощью конструкции WHERE в SQL . Я уже знакомил Вас с ней, но в этой статье решил познакомить с WHERE немного поближе.
Начну с простого примера выборки с использованием конструции WHERE в SQL :
SELECT * FROM table WHERE count=5
Вернутся записи, в которых поле "count " имеет значение 5 . Теперь усложним запрос:
SELECT * FROM table WHERE count=5 AND id < 100
Таким образом, вернутся записи, у которых поле "count " имеет значение 5 И поле "id " имеет значение меньше 100 .
Разумеется, Вы можете использовать и другие логические операции. Их полный список:
Пример с использованием нескольких логических операторов:
SELECT * FROM table WHERE !(id <= 120 AND (count=10 OR date > "10/11/1980"))
Вот такой, на первый взгляд, сложный SQL-запрос . Постарайтесь в нём разобраться самостоятельно.
Также конструкция WHERE в SQL может содержать LIKE . LIKE позволяет определить, совпадает ли указанная строка с определённым шаблоном. Чтобы стало немного понятнее, приведу пример:
SELECT * FROM table WHERE text LIKE "%some text%"
Данный SQL-запрос вернёт result_set , содержащий записи, в которых поле "text " имеет такой текст: "some text ". Обратите внимание, что это не проверка на равенство. Текст может быть огромным, но если в нём содержитася строка: "some text ", то LIKE вернёт true .
Давайте напишу, как задаётся шаблон для LIKE :
Знание и умение использования LIKE очень важно, поверьте моему опыту. Самый простой пример использования LIKE - это поиск по сайту . Ведь контент находится в базе данных, и необходимо вытащить только те записи, в которых содержится строка, заданная в строке поиска. И тут приходит на помощь LIKE . Именно так реализован поиск мною на этом сайте.