2009-08-06 1 views
0

さまざまなクレジットカードタイプで行われたトランザクションの数に関する臨時報告書を作成する必要があります。レポートの目的上、4で始まるすべてのクレジットカードがVISAカードであり、5で始まるクレジットカードがMasterCardであると仮定するのは問題ありません。可変長のinput_expressionによるTransact SQL CASE

このクエリは、上記の区別に適しています。しかし、私たちの状況(これはワールドワイドどのように動作するかわからない)で3で始まるすべてのカードがあるものを除き、ダイナースクラブカードと考えることができ

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 

AMEXカードである37で始まります。このような上記のクエリが完了ハック

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 

のように思えるの拡張

は、最初の2桁は特殊なケースに一致する場合を除き、すべてのケースで最初の桁のグループ化のエレガントな方法はありますか?

私も...

EDIT誰でも手助けしたい場合はどのようにタイトルこの質問見当がつかない:私はマスターカードとVISAの値はこれだけであることを、混同していたが正しい:)あなたは、次のようにcase文を行うことができます

+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 
+2

+1完全な答え。また、ケースステートメントの順序が重要であることを追加する必要があります。 '3'をチェックする前に '37'をチェックしてください。そうでなければ、 '3'が最初に起動します –

1

あなただけのカード型の列を格納することができあなたのテーブルとFKカード型テーブルに、または試みるようなもの:あなたは本当にテーブル内のカードタイプの値を格納する検討すべきである

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

EDIT。挿入するときに一度決定してから、毎回これらのフープを飛び越さずにデータを照会することができます。いくつかの点で、アルゴリズムの変更は、すべての既存のデータは、お使いのシステムに関する正しい

+0

カードタイプをテーブルに保存する方が良い方法でしょう。しかし私たちの大部分のように、皆さんが変更するために他の誰もが恐れているレガシーシステムで作業しなければならないと確信しています。このレポートがより頻繁に実行されるようになると、私はより良い解決策を得るためにもっと激しく戦います。 –

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 
+0

T-SQLの 'end'キーワードが欠けていることは別として、上記のことが私に示唆されています。 – MattH

+0

おっと、 "end"を追加しました - これもOracleに必要です –

1

個人的には、あなたの「長さ」の方法は、@ samjudsonという答えが見つかるよりも読みやすく、管理しやすいという点で、エレガントです(しかし私は彼らのアプローチの魅力が分かります)。 1つのケースにつき2つ以上の値をテストするのに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