在可变长度input_expression上执行SQL CASE

时间:2009-08-06 15:41:08

标签: sql tsql case

我必须就使用不同信用卡类型进行的交易数量制作临时报告。出于报告的目的,可以假设所有以4开头的信用卡都是VISA卡,而以5开头的信用卡是万事达卡。

此查询适用于上述区别:

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

然而,在我们的情况下(不确定这是如何在世界范围内工作)所有以3开头的牌都可以被视为大莱卡,除了那些以37开头的AMEX卡。

像这样扩展上面的查询似乎是一个完整的黑客

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

除了前两位与特殊情况相符​​的情况外,是否有一种优雅的方法可以在所有情况下按第一位分组?

我也不知道怎么标题这个问题如果有人想帮忙......

编辑:我将MasterCard和VISA的值混为一谈,所以只是为了正确:)

4 个答案:

答案 0 :(得分:5)

您可以执行以下案例陈述:

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

答案 1 :(得分:2)

不确定您的系统,但在Oracle CASE表达式中就是这样,所以您可以嵌套它们:

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

答案 2 :(得分:1)

您可以将卡片类型列存储在表格中,将FK存储到卡片类型表格中,或尝试以下操作:

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

修改
你应该考虑在表格中存储卡片类型值。插入时确定一次,然后您可以查询数据,而不必每次跳过这些箍。如果算法在某个时刻发生变化,所有现有数据都是正确的

,您也将保护自己

答案 3 :(得分:1)

就我个人而言,我认为你的“长手”方式很优雅,因为它比我找到@samjudson的答案更容易阅读和维护(但我确实看到了他们的方法的吸引力)。您可以使用OR来测试每个案例的多个值。我发现LIKE更容易阅读,但这可能只是我;)例如

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