Pregunta

Tengo que producir un informe ad-hoc sobre la cantidad de transacciones realizadas con diferentes tipos de tarjetas de crédito. A los fines del informe, está bien asumir que todas las tarjetas de crédito que comienzan con un 4 son tarjetas de visa y que las que comienzan con un 5 son MasterCard.

Esta consulta funciona bien para las distinciones anteriores:

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

Sin embargo, en nuestra situación (no estoy seguro de cómo esto funciona en todo el mundo), todas las tarjetas que comienzan con un 3 pueden considerarse tarjetas de Diners Club, excepto para aquellas que comienzan con un 37 que son tarjetas AMEX.

Extender la consulta anterior como esta parece un truco 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 una forma elegante de agrupar en el primer dígito en todos los casos, excepto donde los dos primeros dígitos coinciden con el caso especial?

Tampoco tengo idea de cómo Título Esta pregunta si alguien quiere ayudar ...

EDITAR: Tenía los valores para MasterCard y Visa mezclados, así que solo para ser correcto :)

¿Fue útil?

Solución

Puede hacer declaraciones de casos como las siguientes:

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

Otros consejos

No estoy seguro de su sistema, pero en Oracle Case las expresiones son exactamente eso, por lo que puede anidarlos:

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

Simplemente puede almacenar la columna de tipo de tarjeta en su tabla y FK en una tabla tipo tarjeta, o probar algo como:

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

EDITAR
Realmente debería considerar almacenar un valor de tipo de tarjeta en una tabla. Determínelo una vez al insertar y luego puede consultar sus datos sin saltar a través de estos aros cada vez. También se protegerá si el algoritmo cambia en algún momento, todos los datos existentes serán correctos

Personalmente, creo que su forma de 'larga distancia' es elegante, ya que es fácil de leer y mantener de lo que encontraría la respuesta @Samjudson (pero sí veo el atractivo de su enfoque). Podrías usar OR para probar más de un valor por caso. Encuentro LIKE más fácil de leer, pero eso podría ser yo;) por ejemplo

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top