• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Shuffy

            不斷的學(xué)習(xí),不斷的思考,才能不斷的進(jìn)步.Let's do better together!
            posts - 102, comments - 43, trackbacks - 0, articles - 19

            SQL CASE WHEN使用

            Posted on 2011-04-22 13:19 Shuffy 閱讀(783) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 在線(xiàn)推薦閱讀
            Case具有兩種格式。簡(jiǎn)單Case函數(shù)和Case搜索函數(shù)。
            --簡(jiǎn)單Case函數(shù)
            CASE sex
            WHEN '1' THEN '男'
            WHEN '2' THEN '女'
            ELSE '其他' END
            --Case搜索函數(shù)
            CASE WHEN sex = '1' THEN '男'
            WHEN sex = '2' THEN '女'
            ELSE '其他' END
            

            這兩種方式,可以實(shí)現(xiàn)相同的功能。簡(jiǎn)單Case函數(shù)的寫(xiě)法相對(duì)比較簡(jiǎn)潔,但是和Case搜索函數(shù)相比,功能方面會(huì)有些限制,比如寫(xiě)判斷式。
            還有一個(gè)需要注意的問(wèn)題,Case函數(shù)只返回第一個(gè)符合條件的值,剩下的Case部分將會(huì)被自動(dòng)忽略。
            --比如說(shuō),下面這段SQL,你永遠(yuǎn)無(wú)法得到“第二類(lèi)”這個(gè)結(jié)果
            CASE WHEN col_1 IN ( 'a', 'b') THEN '第一類(lèi)'
            WHEN col_1 IN ('a')       THEN '第二類(lèi)'
            ELSE'其他' END

            下面我們來(lái)看一下,使用Case函數(shù)都能做些什么事情。

            一,已知數(shù)據(jù)按照另外一種方式進(jìn)行分組,分析。

            有如下數(shù)據(jù):(為了看得更清楚,我并沒(méi)有使用國(guó)家代碼,而是直接用國(guó)家名作為Primary Key)
            國(guó)家(country) 人口(population)
            中國(guó) 600
            美國(guó) 100
            加拿大 100
            英國(guó) 200
            法國(guó) 300
            日本 250
            德國(guó) 200
            墨西哥 50
            印度 250

            根據(jù)這個(gè)國(guó)家人口數(shù)據(jù),統(tǒng)計(jì)亞洲和北美洲的人口數(shù)量。應(yīng)該得到下面這個(gè)結(jié)果。
            人口
            亞洲 1100
            北美洲 250
            其他 700

            想要解決這個(gè)問(wèn)題,你會(huì)怎么做?生成一個(gè)帶有洲Code的View,是一個(gè)解決方法,但是這樣很難動(dòng)態(tài)的改變統(tǒng)計(jì)的方式。
            如果使用Case函數(shù),SQL代碼如下:
            SELECT  SUM(population),
            CASE country
            WHEN '中國(guó)'     THEN '亞洲'
            WHEN '印度'     THEN '亞洲'
            WHEN '日本'     THEN '亞洲'
            WHEN '美國(guó)'     THEN '北美洲'
            WHEN '加拿大'  THEN '北美洲'
            WHEN '墨西哥'  THEN '北美洲'
            ELSE '其他' END
            FROM    Table_A
            GROUP BY CASE country
            WHEN '中國(guó)'     THEN '亞洲'
            WHEN '印度'     THEN '亞洲'
            WHEN '日本'     THEN '亞洲'
            WHEN '美國(guó)'     THEN '北美洲'
            WHEN '加拿大'  THEN '北美洲'
            WHEN '墨西哥'  THEN '北美洲'
            ELSE '其他' END;
            

            同樣的,我們也可以用這個(gè)方法來(lái)判斷工資的等級(jí),并統(tǒng)計(jì)每一等級(jí)的人數(shù)。SQL代碼如下;
            SELECT
            CASE WHEN salary <= 500 THEN '1'
            WHEN salary > 500 AND salary <= 600  THEN '2'
            WHEN salary > 600 AND salary <= 800  THEN '3'
            WHEN salary > 800 AND salary <= 1000 THEN '4'
            ELSE NULL END salary_class,
            COUNT(*)
            FROM    Table_A
            GROUP BY
            CASE WHEN salary <= 500 THEN '1'
            WHEN salary > 500 AND salary <= 600  THEN '2'
            WHEN salary > 600 AND salary <= 800  THEN '3'
            WHEN salary > 800 AND salary <= 1000 THEN '4'
            ELSE NULL END;
            

            二,用一個(gè)SQL語(yǔ)句完成不同條件的分組。

            有如下數(shù)據(jù)
            國(guó)家(country) 性別(sex) 人口(population)
            中國(guó) 1 340
            中國(guó) 2 260
            美國(guó) 1 45
            美國(guó) 2 55
            加拿大 1 51
            加拿大 2 49
            英國(guó) 1 40
            英國(guó) 2 60

            按照國(guó)家和性別進(jìn)行分組,得出結(jié)果如下
            國(guó)家
            中國(guó) 340 260
            美國(guó) 45 55
            加拿大 51 49
            英國(guó) 40 60

            普通情況下,用UNION也可以實(shí)現(xiàn)用一條語(yǔ)句進(jìn)行查詢(xún)。但是那樣增加消耗(兩個(gè)Select部分),而且SQL語(yǔ)句會(huì)比較長(zhǎng)。
            下面是一個(gè)是用Case函數(shù)來(lái)完成這個(gè)功能的例子
            SELECT country,
            SUM( CASE WHEN sex = '1' THEN
            population ELSE 0 END),  --男性人口
            SUM( CASE WHEN sex = '2' THEN
            population ELSE 0 END)   --女性人口
            FROM  Table_A
            GROUP BY country;
            

            這樣我們使用Select,完成對(duì)二維表的輸出形式,充分顯示了Case函數(shù)的強(qiáng)大。

            三,在Check中使用Case函數(shù)。

            在Check中使用Case函數(shù)在很多情況下都是非常不錯(cuò)的解決方法。可能有很多人根本就不用Check,那么我建議你在看過(guò)下面的例子之后也嘗試一下在SQL中使用Check。
            下面我們來(lái)舉個(gè)例子
            公司A,這個(gè)公司有個(gè)規(guī)定,女職員的工資必須高于1000塊。如果用Check和Case來(lái)表現(xiàn)的話(huà),如下所示
            CONSTRAINT check_salary CHECK
            ( CASE WHEN sex = '2'
            THEN CASE WHEN salary > 1000
            THEN 1 ELSE 0 END
            ELSE 1 END = 1 )
            

            如果單純使用Check,如下所示
            CONSTRAINT check_salary CHECK
            ( sex = '2' AND salary > 1000 )
            

            女職員的條件倒是符合了,男職員就無(wú)法輸入了。
            四,根據(jù)條件有選擇的UPDATE。

            例,有如下更新條件
            1. 工資5000以上的職員,工資減少10%
            2. 工資在2000到4600之間的職員,工資增加15%
            很容易考慮的是選擇執(zhí)行兩次UPDATE語(yǔ)句,如下所示
            --條件1
            UPDATE Personnel
            SET salary = salary * 0.9
            WHERE salary >= 5000;
            --條件2
            UPDATE Personnel
            SET salary = salary * 1.15
            WHERE salary >= 2000 AND salary < 4600;
            

            但是事情沒(méi)有想象得那么簡(jiǎn)單,假設(shè)有個(gè)人工資5000塊。首先,按照條件1,工資減少10%,變成工資4500。接下來(lái)運(yùn)行第二個(gè)SQL時(shí)候,因?yàn)檫@個(gè)人的工資是4500在2000到4600的范圍之內(nèi), 需增加15%,最后這個(gè)人的工資結(jié)果是5175,不但沒(méi)有減少,反而增加了。如果要是反過(guò)來(lái)執(zhí)行,那么工資4600的人相反會(huì)變成減少工資。暫且不管這個(gè)規(guī)章是多么荒誕,如果想要一個(gè)SQL 語(yǔ)句實(shí)現(xiàn)這個(gè)功能的話(huà),我們需要用到Case函數(shù)。代碼如下:
            UPDATE Personnel
            SET salary = CASE WHEN salary >= 5000
                         THEN salary * 0.9
            WHEN salary >= 2000 AND salary < 4600
            THEN salary * 1.15
            ELSE salary END;
            

            這里要注意一點(diǎn),最后一行的ELSE salary是必需的,要是沒(méi)有這行,不符合這兩個(gè)條件的人的工資將會(huì)被寫(xiě)成NUll,那可就大事不妙了。在Case函數(shù)中Else部分的默認(rèn)值是NULL,這點(diǎn)是需要注意的地方。
            這種方法還可以在很多地方使用,比如說(shuō)變更主鍵這種累活。
            一般情況下,要想把兩條數(shù)據(jù)的Primary key,a和b交換,需要經(jīng)過(guò)臨時(shí)存儲(chǔ),拷貝,讀回?cái)?shù)據(jù)的三個(gè)過(guò)程,要是使用Case函數(shù)的話(huà),一切都變得簡(jiǎn)單多了。
            p_key col_1 col_2
            a 1 張三
            b 2 李四
            c 3 王五


            假設(shè)有如上數(shù)據(jù),需要把主鍵ab相互交換。用Case函數(shù)來(lái)實(shí)現(xiàn)的話(huà),代碼如下
            UPDATE SomeTable
            SET p_key = CASE WHEN p_key = 'a'
            THEN 'b'
            WHEN p_key = 'b'
            THEN 'a'
            ELSE p_key END
            WHERE p_key IN ('a', 'b');
            

            同樣的也可以交換兩個(gè)Unique key。需要注意的是,如果有需要交換主鍵的情況發(fā)生,多半是當(dāng)初對(duì)這個(gè)表的設(shè)計(jì)進(jìn)行得不夠到位,建議檢查表的設(shè)計(jì)是否妥當(dāng)。

            五,兩個(gè)表數(shù)據(jù)是否一致的檢查。

            Case函數(shù)不同于DECODE函數(shù)。在Case函數(shù)中,可以使用BETWEEN,LIKE,IS NULL,IN,EXISTS等等。比如說(shuō)使用IN,EXISTS,可以進(jìn)行子查詢(xún),從而 實(shí)現(xiàn)更多的功能。
            下面具個(gè)例子來(lái)說(shuō)明,有兩個(gè)表,tbl_A,tbl_B,兩個(gè)表中都有keyCol列。現(xiàn)在我們對(duì)兩個(gè)表進(jìn)行比較,tbl_A中的keyCol列的數(shù)據(jù)如果在tbl_B的keyCol列的數(shù)據(jù)中可以找到, 返回結(jié)果'Matched',如果沒(méi)有找到,返回結(jié)果'Unmatched'。
            要實(shí)現(xiàn)下面這個(gè)功能,可以使用下面兩條語(yǔ)句
            --使用IN的時(shí)候
            SELECT keyCol,
            CASE WHEN keyCol IN ( SELECT keyCol FROM tbl_B )
            THEN 'Matched'
            ELSE 'Unmatched' END Label
            FROM tbl_A;
            --使用EXISTS的時(shí)候
            SELECT keyCol,
            CASE WHEN EXISTS ( SELECT * FROM tbl_B
            WHERE tbl_A.keyCol = tbl_B.keyCol )
            THEN 'Matched'
            ELSE 'Unmatched' END Label
            FROM tbl_A;
            

            使用IN和EXISTS的結(jié)果是相同的。也可以使用NOT IN和NOT EXISTS,但是這個(gè)時(shí)候要注意NULL的情況。

            六,在Case函數(shù)中使用合計(jì)函數(shù)

            假設(shè)有下面一個(gè)表
            學(xué)號(hào)(std_id) 課程ID(class_id) 課程名(class_name) 主修flag(main_class_flg)
            100 1 經(jīng)濟(jì)學(xué) Y
            100 2 歷史學(xué) N
            200 2 歷史學(xué) N
            200 3 考古學(xué) Y
            200 4 計(jì)算機(jī) N
            300 4 計(jì)算機(jī) N
            400 5 化學(xué) N
            500 6 數(shù)學(xué) N

            有的學(xué)生選擇了同時(shí)修幾門(mén)課程(100,200)也有的學(xué)生只選擇了一門(mén)課程(300,400,500)。選修多門(mén)課程的學(xué)生,要選擇一門(mén)課程作為主修,主修flag里面寫(xiě)入 Y。只選擇一門(mén)課程的學(xué)生,主修flag為N(實(shí)際上要是寫(xiě)入Y的話(huà),就沒(méi)有下面的麻煩事了,為了舉例子,還請(qǐng)多多包含)。
            現(xiàn)在我們要按照下面兩個(gè)條件對(duì)這個(gè)表進(jìn)行查詢(xún)
            1. 只選修一門(mén)課程的人,返回那門(mén)課程的ID
            2. 選修多門(mén)課程的人,返回所選的主課程ID

            簡(jiǎn)單的想法就是,執(zhí)行兩條不同的SQL語(yǔ)句進(jìn)行查詢(xún)。
            條件1
            --條件1:只選擇了一門(mén)課程的學(xué)生
            SELECT std_id, MAX(class_id) AS main_class
            FROM Studentclass
            GROUP BY std_id
            HAVING COUNT(*) = 1;
            

            執(zhí)行結(jié)果1
            STD_ID   MAIN_class
            ------   ----------
            300      4
            400      5
            500      6
            

            條件2
            --條件2:選擇多門(mén)課程的學(xué)生
            SELECT std_id, class_id AS main_class
            FROM Studentclass
            WHERE main_class_flg = 'Y' ;
            

            執(zhí)行結(jié)果2
            STD_ID  MAIN_class
            ------  ----------
            100     1
            200     3
            

            如果使用Case函數(shù),我們只要一條SQL語(yǔ)句就可以解決問(wèn)題,具體如下所示
            SELECT  std_id,
            CASE WHEN COUNT(*) = 1  --只選擇一門(mén)課程的學(xué)生的情況
            THEN MAX(class_id)
            ELSE MAX(CASE WHEN main_class_flg = 'Y'
            THEN class_id
            ELSE NULL END
            )
            END AS main_class
            FROM Studentclass
            GROUP BY std_id;
            

            運(yùn)行結(jié)果
            STD_ID   MAIN_class
            ------   ----------
            100      1
            200      3
            300      4
            400      5
            500      6
            

            通過(guò)在Case函數(shù)中嵌套Case函數(shù),在合計(jì)函數(shù)中使用Case函數(shù)等方法,我們可以輕松的解決這個(gè)問(wèn)題。使用Case函數(shù)給我們帶來(lái)了更大的自由度。
            最后提醒一下使用Case函數(shù)的新手注意不要犯下面的錯(cuò)誤
            CASE col_1
            WHEN 1        THEN 'Right'
            WHEN NULL  THEN 'Wrong'
            END
            


            在這個(gè)語(yǔ)句中When Null這一行總是返回unknown,所以永遠(yuǎn)不會(huì)出現(xiàn)Wrong的情況。因?yàn)檫@句可以替換成WHEN col_1 = NULL,這是一個(gè)錯(cuò)誤的用法,這個(gè)時(shí)候我們應(yīng)該選擇用WHEN col_1 IS NULL。

            麻豆精品久久久一区二区| 久久亚洲天堂| 情人伊人久久综合亚洲| 国产精品欧美亚洲韩国日本久久| 久久99精品久久久久久水蜜桃| 性做久久久久久久久久久| 色综合久久无码中文字幕| 精品久久久久久无码专区不卡| 久久久久久久久久久免费精品| 久久精品国产免费观看三人同眠| 国产精品久久影院| 久久亚洲国产精品成人AV秋霞| 国产精品欧美久久久天天影视| 国产精品99久久久久久宅男小说| 久久久久久a亚洲欧洲aⅴ | 狠狠色丁香婷婷综合久久来来去| 色综合久久中文字幕综合网| 国产亚洲美女精品久久久久狼| 亚洲欧美另类日本久久国产真实乱对白 | 怡红院日本一道日本久久| 亚洲精品成人久久久| 青青草国产精品久久| 亚洲av成人无码久久精品| 午夜精品久久久久久久无码| 青青草原综合久久| 国产成年无码久久久久毛片| 久久人人爽人人爽人人爽| 久久精品国产亚洲Aⅴ香蕉| 97久久精品无码一区二区| 久久久久AV综合网成人| 午夜天堂av天堂久久久| 久久综合久久美利坚合众国| 性做久久久久久免费观看| 色欲综合久久躁天天躁| 久久精品国产清自在天天线| 激情久久久久久久久久| 久久影院久久香蕉国产线看观看| 久久99精品久久久久久9蜜桃| 久久精品免费网站网| 久久久久国产精品三级网| 久久天天躁狠狠躁夜夜2020|