Главная » Просмотр файлов » alan_beaulieu-learning_sql-ru

alan_beaulieu-learning_sql-ru (865932), страница 39

Файл №865932 alan_beaulieu-learning_sql-ru (Учебник по SQL) 39 страницаalan_beaulieu-learning_sql-ru (865932) страница 392022-01-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 39)

Чтобы понять,что имеется в виду, рассмотрим выражение case с перебором вариантов,логика которого аналогична предыдущему простому выражению case.Примеры выражений case221CASEWHEN customer.cust_type_cd = 'I' THEN(SELECT CONCAT(i.fname, ' ', i.lname)FROM individual IWHERE i.cust_id = customer.cust_id)WHEN customer.cust_type_cd = 'B' THEN(SELECT b.nameFROM business bWHERE b.cust_id = customer.cust_id)ELSE 'Unknown Customer Type'ENDВыражения case с перебором вариантов позволяют создавать условиявхождения в диапазон, условия неравенства и составные условия, использующие and/or/not, поэтому я бы рекомендовал применять выражения case с перебором вариантов во всех случаях, кроме самых простых.Примеры выражений caseСледующие разделы представляют различные примеры, иллюстрирующие применение условной логики в SQLвыражениях.Трансформации результирующих наборовИногда агрегирование проводится по конечному набору значений, например по дням недели, но требуется, чтобы результирующий наборвключал всего одну строку с количеством столбцов, соответствующимколичеству значений, а не по одной строке на каждое значение.

В качестве примера возьмем запрос, возвращающий число счетов, открытых в каждом году, начиная с 2000 года:mysql> SELECT YEAR(open_date) year, COUNT(*) how_many> FROM account> WHERE open_date > '19991231'> GROUP BY YEAR(open_date);+++| year | how_many |+++| 2000 |3 || 2001 |4 || 2002 |5 || 2003 |3 || 2004 |9 |+++5 rows in set (0.00 sec)Чтобы трансформировать этот результирующий набор в одну строкус шестью столбцами (по одному для каждого года, с 2000 по 2005), понадобится создать шесть столбцов и в каждом столбце просуммироватьтолько строки, относящиеся к данному году:222Глава 11.

Условная логикаmysql> SELECT> SUM(CASE>WHEN EXTRACT(YEAR FROM open_date) = 2000 THEN 1>ELSE 0>END) year_2000,> SUM(CASE>WHEN EXTRACT(YEAR FROM open_date) = 2001 THEN 1>ELSE 0>END) year_2001,> SUM(CASE>WHEN EXTRACT(YEAR FROM open_date) = 2002 THEN 1>ELSE 0>END) year_2002,> SUM(CASE>WHEN EXTRACT(YEAR FROM open_date) = 2003 THEN 1>ELSE 0>END) year_2003,> SUM(CASE>WHEN EXTRACT(YEAR FROM open_date) = 2004 THEN 1>ELSE 0>END) year_2004,> SUM(CASE>WHEN EXTRACT(YEAR FROM open_date) = 2005 THEN 1>ELSE 0>END) year_2005> FROM account> WHERE open_date > '19991231';+++++++| year_2000 | year_2001 | year_2002 | year_2003 | year_2004 | year_2005 |+++++++|3 |4 |5 |3 |9 |0 |+++++++1 row in set (0.01 sec)Все шесть выражений для столбцов предыдущего запроса идентичны,за исключением значения года.

Когда функция extract() возвращаетнужный год, выражение case возвращает значение 1. В противном случае возвращается 0. Суммируя все счета, открытые с 2000 года, каждый столбец возвращает число счетов, открытых в соответствующийгод. Очевидно, что такие трансформации практически применимытолько для небольшого числа значений. Решение задачи по формированию столбцов для каждого года, начиная с 1905го, быстро стало быслишком громоздким.Селективная агрегацияРанее в главе 9 было показано частичное решение задачи поиска счетов, остаток на которых не соответствует данным таблицы transaction.Причиной предоставления частичного решения была необходимостьприменения условной логики, но теперь у нас есть все для того, чтобызакончить работу.

Вот на чем я остановился в главе 9:Примеры выражений case223SELECT CONCAT('ALERT! : Account #', a.account_id,' Has Incorrect Balance!')FROM account aWHERE (a.avail_balance, a.pending_balance) <>(SELECT SUM(<expression to generate available balance>),SUM(<expression to generate pending balance>)FROM transaction tWHERE t.account_id = a.account_id);Для суммирования отдельных транзакций по данному счету этот запрос использует связанный подзапрос к таблице transaction.

При суммировании транзакций следует учитывать два факта:• Суммы транзакций всегда положительны, поэтому чтобы понять,является ли транзакция дебетовой или кредитовой, необходимо посмотреть на ее тип и изменить знак (умножить на –1) для дебетовыхтранзакций.• Если дата в столбце funds_avail_date больше текущей, транзакциядолжна быть добавлена в суммарный отложенный остаток, а нев суммарный доступный остаток.Из доступного остатка некоторые транзакции должны быть исключены, а в отложенный остаток включаются все транзакции, что делаетего более простым для вычисления.

Вот выражение case для вычисления отложенного остатка:CASEWHEN transaction.txn_type_cd = 'DBT'THEN transaction.amount * 1ELSE transaction.amountENDТаким образом, все суммы транзакций для дебетовых транзакций умножаются на –1, а для кредитовых транзакций остаются неизменными. Точно такая же логика применяется и к вычислению доступногоостатка, но здесь должны быть включены только те транзакции, которые стали доступными. Поэтому выражение case для вычисления доступного остатка включает один дополнительный блок when:CASEWHEN transaction.funds_avail_date > CURRENT_TIMESTAMP()THEN 0WHEN transaction.txn_type_cd = 'DBT'THEN transaction.amount * 1ELSE transaction.amountENDВ первом блоке when недоступные фонды, такие как неоплаченные чеки, будут добавлять к сумме 0 долларов.

Вот окончательный вариантзапроса с двумя выражениями case:SELECT CONCAT('ALERT! : Account #', a.account_id,' Has Incorrect Balance!')224Глава 11. Условная логикаFROM account aWHERE (a.avail_balance, a.pending_balance) <>(SELECTSUM(CASEWHEN t.funds_avail_date > CURRENT_TIMESTAMP()THEN 0WHEN t.txn_type_cd = 'DBT'THEN t.amount * 1ELSE t.amountEND),SUM(CASEWHEN t.txn_type_cd = 'DBT'THEN t.amount * 1ELSE t.amountEND)FROM transaction tWHERE t.account_id = a.account_id);С помощью условной логики исходные данные поставляются в агрегатные функции sum() двумя выражениями case, позволяя суммировать соответствующие денежные объемы.Проверка существованияВ некоторых случаях требуется установить существование связи между двумя сущностями, не касаясь количественных показателей.

Например, нужно узнать, есть ли у клиента текущие или сберегательныесчета, не интересуясь тем, сколько у него счетов каждого типа. Вот запрос с несколькими выражениями case, формирующими два столбцавыходных данных. Первый показывает, есть ли у клиента текущиесчета, а второй – есть ли сберегательные счета:mysql> SELECT c.cust_id, c.fed_id, c.cust_type_cd,> CASE>WHEN EXISTS (SELECT 1 FROM account a>WHERE a.cust_id = c.cust_id>AND a.product_cd = 'CHK') THEN 'Y'>ELSE 'N'> END has_checking,> CASE>WHEN EXISTS (SELECT 1 FROM account a>WHERE a.cust_id = c.cust_id>AND a.product_cd = 'SAV') THEN 'Y'>ELSE 'N'> END has_savings> FROM customer c;++++++| cust_id | fed_id| cust_type_cd | has_checking | has_savings |++++++|1 | 111111111 | I| Y| Y||2 | 222222222 | I| Y| Y|Примеры выражений case225|3 | 333333333 | I| Y| N||4 | 444444444 | I| Y| Y||5 | 555555555 | I| Y| N||6 | 666666666 | I| Y| N||7 | 777777777 | I| N| N||8 | 888888888 | I| Y| Y||9 | 999999999 | I| Y| N||10 | 041111111 | B| Y| N||11 | 042222222 | B| N| N||12 | 043333333 | B| Y| N||13 | 044444444 | B| N| N|++++++13 rows in set (0.00 sec)Каждое выражение case включает связанный подзапрос к таблице account: один для поиска текущих счетов, другой – сберегательных счетов.

Поскольку каждый блок when использует оператор exists, условиявыполняются, если у клиента есть, по крайней мере, один счет искомого типа.В других случаях нас может интересовать количество встретившихсястрок, но лишь постольку поскольку. Например, следующий запросс помощью простого выражения case подсчитывает количество счетовкаждого клиента, а затем возвращает 'None', '1', '2' или '3+':mysql> SELECT c.cust_id, c.fed_id, c.cust_type_cd,> CASE (SELECT COUNT(*) FROM account a>WHERE a.cust_id = c.cust_id)>WHEN 0 THEN 'None'>WHEN 1 THEN '1'>WHEN 2 THEN '2'>ELSE '3+'> END num_accounts> FROM customer c;+++++| cust_id | fed_id| cust_type_cd | num_accounts |+++++|1 | 111111111 | I| 3+||2 | 222222222 | I| 2||3 | 333333333 | I| 2||4 | 444444444 | I| 3+||5 | 555555555 | I| 1||6 | 666666666 | I| 2||7 | 777777777 | I| 1||8 | 888888888 | I| 2||9 | 999999999 | I| 3+||10 | 041111111 | B| 2||11 | 042222222 | B| 1||12 | 043333333 | B| 1||13 | 044444444 | B| 1|+++++13 rows in set (0.01 sec)226Глава 11.

Условная логикаВ этом запросе я не хотел проводить различия между клиентами, имеющими более двух счетов, поэтому выражение case просто создает категорию '3+'. Подобный запрос может быть полезным при поиске клиентов, с которыми можно связаться и предложить открыть новый счетв банке.Ошибки деления на нульПроводя вычисления, включающие деление, нужно все время заботиться о том, чтобы знаменатель никогда не был равен нулю. Некоторые серверы БД, такие как Oracle Database, встретив нулевой знаменатель, формируют ошибку, а MySQL просто присваивает результату вычисления значение null, как показывает следующий пример:mysql> SELECT 100 / 0;++| 100 / 0 |++|NULL |++1 row in set (0.00 sec)Чтобы защитить вычисления от ошибок или, еще хуже, от загадочногополучения null, следует ко всем знаменателям применять условнуюлогику, как показано далее:mysql> SELECT a.cust_id, a.product_cd, a.avail_balance /> CASE>WHEN prod_tots.tot_balance = 0 THEN 1>ELSE prod_tots.tot_balance> END percent_of_total> FROM account a INNER JOIN> (SELECT a.product_cd, SUM(a.avail_balance) tot_balance> FROM account a> GROUP BY a.product_cd) prod_tots> ON a.product_cd = prod_tots.product_cd;++++| cust_id | product_cd | percent_of_total |++++|10 | BUS|0.0000 ||11 | BUS|1.0000 ||1 | CD|0.1538 ||6 | CD|0.5128 ||7 | CD|0.2564 ||9 | CD|0.0769 ||1 | CHK|0.0145 ||2 | CHK|0.0309 ||3 | CHK|0.0145 ||4 | CHK|0.0073 ||5 | CHK|0.0307 ||6 | CHK|0.0017 |Примеры выражений case227|8 | CHK|0.0478 ||9 | CHK|0.0017 ||10 | CHK|0.3229 ||12 | CHK|0.5281 ||3 | MM|0.1298 ||4 | MM|0.3219 ||9 | MM|0.5483 ||1 | SAV|0.2694 ||2 | SAV|0.1078 ||4 | SAV|0.4137 ||8 | SAV|0.2091 ||13 | SBL|1.0000 |++++24 rows in set (0.00 sec)Этот запрос вычисляет отношение остатка на счете к общему остаткудля всех счетов одного типа.

Характеристики

Тип файла
PDF-файл
Размер
1,22 Mb
Материал
Предмет
Высшее учебное заведение

Список файлов ответов (шпаргалок)

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6264
Авторов
на СтудИзбе
316
Средний доход
с одного платного файла
Обучение Подробнее