Транзакция SQL -корпуса по переменной длине input_expression
Вопрос
Я должен дать специальное отчет о количестве транзакций, выполненных с различными типами кредитных карт. В целях отчета можно предположить, что все кредитные карты, начинающиеся с 4, являются картами Visa, и что те, которые начинаются с 5, являются MasterCard.
Этот запрос хорошо работает для вышеуказанных различий:
select card_type =
case substring(pan,1,1)
when '4' then 'VISA'
when '5' then 'MasterCard'
else 'unknown'
end,count(*),
sum(amount)
from transactions
group by card_type
Однако в нашей ситуации (не уверен, как это работает во всем мире), все карты, начинающиеся с 3, можно считать клубными картами Diners, за исключением тех, которые начинаются с 37, которые являются картами Amex.
Расширение вышеупомянутого запроса, как это кажется полным взломом
select card_type =
case substring(pan,1,2)
when '30' then 'Diners'
...
when '37' then 'AMEX'
...
when '39' then 'Diners'
when '40' then 'VISA'
...
when '49' then 'VISA'
when '50' then 'MasterCard'
...
when '59' then 'MasterCard'
else 'unknown'
end,count(*),
sum(amount)
from transactions
group by card_type
Есть ли элегантный способ группировки первой цифрой во всех случаях, за исключением случаев, когда первые две цифры соответствуют специальному корпусу?
Я также понятия не имею, как Заголовок Этот вопрос, если кто -то хочет помочь ...
РЕДАКТИРОВАТЬ: У меня были значения для MasterCard и Visa, так что просто чтобы быть правильным :)
Решение
Вы можете делать операторы для случая, например, следующие:
select case
when substring(pan,1,2) = '37' then 'AMEX'
when substring(pan,1,1) = '3' then 'Diners'
when substring(pan,1,1) = '4' then 'Mastercard'
when substring(pan,1,1) = '5' then 'VISA'
else 'unknown'
end,
count(*),
sum(amount)
from transactions
group by card_type
Другие советы
Не уверен в вашей системе, но в Oracle Case Arpressions именно такими, поэтому вы можете их гнездиться:
case substring(pan,1,1)
when '3' then case substring(pan,2,1)
when '7' then 'Amex'
else 'Diners'
end
when '4' then 'VISA'
when '5' then 'MasterCard'
else 'unknown'
end
Вы можете просто сохранить столбец типа карты в своей таблице и FK в таблице типа карты или попробовать что -то вроде:
CASE
WHEN LEFT(pan,2)='37' then ...
WHEN LEFT(pan,1)='3' then ...
.....
РЕДАКТИРОВАТЬ
Вы должны действительно рассмотреть возможность хранения значения типа карты в таблице. Определите это один раз при вставке, а затем вы можете запросить свои данные, не прыгая через эти обручи каждый раз. Вы также защитите себя, если алгоритм изменится в какой -то момент, все существующие данные будут правильными
Лично я думаю, что ваш способ «Longhand» элегантен в том смысле, что его легко читать и поддерживать, чем я найду ответ @samjudson (но я вижу привлекательность их подхода). Вы могли бы использовать OR
проверить более одного значения на случай. я нахожу LIKE
легче читать, но это может быть просто я;) Например
CASE
WHEN card_type LIKE '37%'
THEN 'AMEX'
WHEN (
card_type LIKE '30%'
OR card_type LIKE '39%'
)
THEN 'Diners'
WHEN (
card_type LIKE '40%'
OR card_type LIKE '49%'
)
THEN 'VISA'
WHEN (
card_type LIKE '50%'
OR card_type LIKE '59%'
)
THEN 'MasterCard'
ELSE
'unknown'
END