Domanda

Devo produrre un rapporto ad hoc sul numero di transazioni effettuate con diversi tipi di carta di credito. Ai fini del rapporto va bene supporre che tutte le carte di credito che iniziano con una 4 siano carte Visa e che quelle che iniziano con un 5 siano MasterCard.

Questa query funziona bene per le distinzioni di cui sopra:

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

Tuttavia, nella nostra situazione (non sono sicuro di come funzioni in tutto il mondo) tutte le carte che iniziano con un 3 possono essere considerate le carte del club dei Diners, tranne per quelle che iniziano con un 37 che sono carte Amex.

Estensione della query sopra come questa sembra un 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

Esiste un modo elegante di raggrupparsi dalla prima cifra in tutti i casi, tranne in cui le prime due cifre corrispondono al caso speciale?

Inoltre non ho idea di come farlo Titolo Questa domanda se qualcuno vuole dare una mano ...

MODIFICARE: Avevo i valori per MasterCard e Visa mescolati, quindi solo per essere corretti :)

È stato utile?

Soluzione

Puoi fare dichiarazioni casi come le seguenti:

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

Altri suggerimenti

Non sono sicuro del tuo sistema, ma nelle espressioni di Oracle Case sono esattamente questo, quindi puoi nidirle:

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

Potresti semplicemente archiviare la colonna del tipo di carta nella tua tabella e FK su una tabella del tipo di carta o provare qualcosa come:

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

MODIFICARE
Dovresti davvero prendere in considerazione la memorizzazione di un valore del tipo di carta in una tabella. Determinalo una volta quando si inserisce e quindi è possibile interrogare i dati senza saltare attraverso questi cerchi ogni volta. Ti proteggerai anche se l'algoritmo cambia ad un certo punto, tutti i dati esistenti saranno corretti

Personalmente, penso che il tuo modo "longhand" sia elegante in quanto è facile da leggere e mantenere di quanto troverei la risposta @samjudson (ma vedo l'appello del loro approccio). Potresti usare OR per testare più di un valore per caso. io trovo LIKE più facile da leggere ma questo potrebbe essere solo io;) ad es.

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top