Pergunta

Eu tenho que produzir um relatório ad-hoc sobre o número de transações feitas com diferentes tipos de cartão de crédito. Para os propósitos do relatório, é bom assumir que todos os cartões de crédito que começam com um 4 são cartões Visa e que aqueles que começam com um 5 são MasterCard.

Esta consulta funciona bem para as distinções acima:

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

No entanto, em nossa situação (não tenho certeza de como isso funciona em todo o mundo), todos os cartões que começam com um 3 podem ser considerados cartões de clubes do Diners, exceto para aqueles que começam com 37 que são cartões Amex.

Estendendo a consulta acima como essa parece um hack completo

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

Existe uma maneira elegante de agrupar o primeiro dígito em todos os casos, exceto onde os dois primeiros dígitos correspondem ao caso especial?

Eu também não tenho ideia de como Título Esta pergunta se alguém quiser ajudar ...

EDITAR: Eu tinha os valores para MasterCard e Visa misturados, então apenas para estar correto :)

Foi útil?

Solução

Você pode fazer declarações de caso como as seguintes:

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

Outras dicas

Não tenho certeza sobre o seu sistema, mas nas expressões de casos Oracle são exatamente isso, para que você possa aninhar -os:

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

Você pode simplesmente armazenar a coluna do tipo de cartão em sua tabela e FK em uma tabela do tipo de cartão ou tentar algo como:

CASE
    WHEN LEFT(pan,2)='37' then ...
    WHEN LEFT(pan,1)='3' then ...
    .....

EDITAR
Você realmente deve considerar armazenar um valor do tipo de cartão em uma tabela. Determine uma vez quando a inserção e, em seguida, você pode consultar seus dados sem pular esses aros a cada vez. Você também se protegerá se o algoritmo mudar em algum momento, todos os dados existentes estarão corretos

Pessoalmente, acho que o seu jeito "de cabeceira" é elegante, pois é fácil de ler e manter do que eu encontraria a resposta @samjudson (mas vejo o apelo de sua abordagem). Você poderia usar OR Para testar mais de um valor por caso. eu acho LIKE mais fácil de ler, mas isso poderia ser apenas eu;) por exemplo

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top