TRANSAKT SQL -Fall über eine variable Länge input_expression
Frage
Ich muss einen Ad-hoc-Bericht über die Anzahl der Transaktionen mit unterschiedlichen Kreditkartentypen erstellen. Für die Zwecke des Berichts ist es in Ordnung anzunehmen, dass alle Kreditkarten, die mit einer 4 beginnen, Visumkarten sind und dass diejenigen, die mit einer 5 beginnen, MasterCard sind.
Diese Abfrage eignet sich gut für die obigen Unterscheidungen:
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
In unserer Situation (nicht sicher, wie dies weltweit funktioniert) können alle Karten, die mit einem 3 beginnen, als Diners Club -Karten angesehen werden, mit Ausnahme derjenigen, die mit einer 37 -Karten beginnen.
Die Erweiterung der obigen Abfrage wie diese scheint ein vollständiger Hack zu sein
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
Gibt es in allen Fällen eine elegante Art der Gruppierung nach der ersten Ziffer, außer wenn die ersten beiden Ziffern mit dem Sonderfall übereinstimmen?
Ich habe auch keine Ahnung, wie ich Titel Diese Frage, wenn jemand helfen möchte ...
BEARBEITEN: Ich hatte die Werte für MasterCard und Visa durcheinander, also um richtig zu sein :)
Lösung
Sie können Fallanweisungen wie folgt ausführen:
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
Andere Tipps
Ich bin mir nicht sicher über Ihr System, aber in Oracle Case -Ausdrücken sind genau das, sodass Sie sie nisten können:
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
Sie können einfach die Kartentypsspalte in Ihrer Tabelle und FK in einer Kartentabelle speichern oder etwas ausprobieren wie:
CASE
WHEN LEFT(pan,2)='37' then ...
WHEN LEFT(pan,1)='3' then ...
.....
BEARBEITEN
Sie sollten wirklich in Betracht ziehen, einen Kartentyp -Wert in einer Tabelle zu speichern. Bestimmen Sie es einmal beim Einfügen und dann können Sie Ihre Daten abfragen, ohne jedes Mal durch diese Reifen zu springen. Sie schützen sich auch, wenn sich der Algorithmus irgendwann ändert, alle vorhandenen Daten sind korrekt
Persönlich denke ich, dass Ihr „langer“ Weg insofern elegant ist, als es leicht zu lesen und zu warten ist, als ich die Antwort @samjudson finden würde (aber ich sehe die Attraktivität ihres Ansatzes). Du könntest benutzen OR
mehr als einen Wert pro Fall testen. ich finde LIKE
leichter zu lesen, aber das könnte nur ich sein;) zB
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