Изучаем sql


ELSE 0 > END) year_2003



Pdf көрінісі
бет196/261
Дата28.07.2022
өлшемі1,6 Mb.
#147825
1   ...   192   193   194   195   196   197   198   199   ...   261
Байланысты:
Изучаем SQL ( PDFDrive )

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:


Примеры выражений case
223
SELECT CONCAT('ALERT! : Account #', a.account_id,
' Has Incorrect Balance!')
FROM account a
WHERE (a.avail_balance, a.pending_balance) <>
(SELECT SUM(),
SUM()
FROM transaction t
WHERE t.account_id = a.account_id);
Для суммирования отдельных транзакций по данному счету этот за
прос использует связанный подзапрос к таблице 
transaction
. При сум
мировании транзакций следует учитывать два факта:

Суммы транзакций всегда положительны, поэтому чтобы понять,
является ли транзакция дебетовой или кредитовой, необходимо по
смотреть на ее тип и изменить знак (умножить на 

1) для дебетовых
транзакций.

Если дата в столбце 
funds_avail_date
больше текущей, транзакция
должна быть добавлена в суммарный отложенный остаток, а не
в суммарный доступный остаток.
Из доступного остатка некоторые транзакции должны быть исключе
ны, а в отложенный остаток включаются все транзакции, что делает
его более простым для вычисления. Вот выражение 
case
для вычисле
ния отложенного остатка:
CASE
WHEN transaction.txn_type_cd = 'DBT'
THEN transaction.amount * 1
ELSE transaction.amount
END
Таким образом, все суммы транзакций для дебетовых транзакций ум
ножаются на 

1, а для кредитовых транзакций остаются неизменны
ми. Точно такая же логика применяется и к вычислению доступного
остатка, но здесь должны быть включены только те транзакции, кото
рые стали доступными. Поэтому выражение 
case
для вычисления дос
тупного остатка включает один дополнительный блок 
when
:
CASE
WHEN transaction.funds_avail_date > CURRENT_TIMESTAMP()
THEN 0
WHEN transaction.txn_type_cd = 'DBT'
THEN transaction.amount * 1
ELSE transaction.amount
END
В первом блоке 
when
недоступные фонды, такие как неоплаченные че
ки, будут добавлять к сумме 0 долларов. Вот окончательный вариант
запроса с двумя выражениями 
case
:
SELECT CONCAT('ALERT! : Account #', a.account_id,
' Has Incorrect Balance!')


224

Достарыңызбен бөлісу:
1   ...   192   193   194   195   196   197   198   199   ...   261




©engime.org 2024
әкімшілігінің қараңыз

    Басты бет