TRANSACTIVER CAS SQL SUR UNE LONGUEUR VARIABLE INPUT_EXPRESSION
Question
Je dois produire un rapport ad hoc sur le nombre de transactions effectuées avec différents types de cartes de crédit. Aux fins du rapport, il est bon de supposer que toutes les cartes de crédit qui commencent par un 4 sont des cartes Visa et que celles qui commencent par un 5 sont MasterCard.
Cette requête fonctionne bien pour les distinctions ci-dessus:
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
Cependant, dans notre situation (je ne sais pas comment cela fonctionne dans le monde entier), toutes les cartes qui commencent par un 3 peuvent être considérées comme des cartes Diners Club, à l'exception de celles qui commencent par un 37 qui sont des cartes Amex.
Étendre la requête ci-dessus comme celle-ci semble être un hack complet
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-t-il un moyen élégant de se regrouper par le premier chiffre dans tous les cas, sauf lorsque les deux premiers chiffres correspondent au cas spécial?
Je ne sais pas non plus comment Titre Cette question si quelqu'un veut aider ...
ÉDITER: J'avais les valeurs pour MasterCard et Visa mélangées, donc juste pour être correct :)
La solution
Vous pouvez faire des instructions de cas comme ce qui suit:
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
Autres conseils
Je ne suis pas sûr de votre système, mais dans Oracle Case, les expressions sont exactement cela, vous pouvez donc les nid:
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
Vous pouvez simplement stocker la colonne de type de carte dans votre table et FK sur une table de type de carte, ou essayer quelque chose comme:
CASE
WHEN LEFT(pan,2)='37' then ...
WHEN LEFT(pan,1)='3' then ...
.....
ÉDITER
Vous devriez vraiment envisager de stocker une valeur de type de carte dans un tableau. Déterminez-le une fois lors de l'insertion, puis vous pouvez interroger vos données sans sauter à travers ces cerceaux à chaque fois. Vous vous protégerez également si l'algorithme change à un moment donné, toutes les données existantes seront correctes
Personnellement, je pense que votre manière «à la main» est élégante en ce qu'il est facile de lire et de maintenir que je ne trouverais la réponse @samjudson (mais je vois l'attrait de leur approche). Vous pourriez utiliser OR
pour tester plus d'une valeur par cas. je trouve LIKE
plus facile à lire mais cela pourrait être moi;) Par exemple
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