Транзакция SQL -корпуса по переменной длине input_expression

StackOverflow https://stackoverflow.com/questions/1239759

  •  11-09-2019
  •  | 
  •  

Вопрос

Я должен дать специальное отчет о количестве транзакций, выполненных с различными типами кредитных карт. В целях отчета можно предположить, что все кредитные карты, начинающиеся с 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top