日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

SQL中条件和比较关键字Case的使用方法(case的结果就是得到了一个值)

發(fā)布時(shí)間:2024/6/5 数据库 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL中条件和比较关键字Case的使用方法(case的结果就是得到了一个值) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Case具有兩種格式。簡(jiǎn)單Case函數(shù)和Case搜索函數(shù)。 --簡(jiǎn)單Case函數(shù)
CASEsex
WHEN'1'THEN'男'
WHEN'2'THEN'女'
ELSE'其他'END
--Case搜索函數(shù)
CASEWHENsex = '1'THEN'男'
WHENsex = '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é)果
CASEWHENcol_1 IN( 'a' , 'b' ) THEN'第一類(lèi)'
WHENcol_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代碼如下: SELECTSUM(population),
CASEcountry
WHEN'中國(guó)'THEN'亞洲'
WHEN'印度'THEN'亞洲'
WHEN'日本'THEN'亞洲'
WHEN'美國(guó)'THEN'北美洲'
WHEN'加拿大'THEN'北美洲'
WHEN'墨西哥'THEN'北美洲'
ELSE'其他'END
FROMTable_A
GROUPBYCASEcountry
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
CASEWHENsalary <= 500 THEN'1'
WHENsalary > 500 ANDsalary <= 600 THEN'2'
WHENsalary > 600 ANDsalary <= 800 THEN'3'
WHENsalary > 800 ANDsalary <= 1000 THEN'4'
ELSENULLENDsalary_class,
COUNT(*)
FROMTable_A
GROUPBY
CASEWHENsalary <= 500 THEN'1'
WHENsalary > 500 ANDsalary <= 600 THEN'2'
WHENsalary > 600 ANDsalary <= 800 THEN'3'
WHENsalary > 800 ANDsalary <= 1000 THEN'4'
ELSENULLEND ;

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

有如下數(shù)據(jù)
國(guó)家(country)性別(sex)人口(population)
中國(guó)1340
中國(guó)2260
美國(guó)145
美國(guó)255
加拿大151
加拿大249
英國(guó)140
英國(guó)260

按照國(guó)家和性別進(jìn)行分組,得出結(jié)果如下
國(guó)家
中國(guó)340260
美國(guó)4555
加拿大5149
英國(guó)4060

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

這樣我們使用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)的話,如下所示 CONSTRAINTcheck_salary CHECK
( CASEWHENsex = '2'
THENCASEWHENsalary > 1000
THEN1 ELSE0 END
ELSE1 END= 1 )

如果單純使用Check,如下所示
CONSTRAINTcheck_salary CHECK
( sex = '2'ANDsalary > 1000 )

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

例,有如下更新條件
  • 工資5000以上的職員,工資減少10%
  • 工資在2000到4600之間的職員,工資增加15%
  • 很容易考慮的是選擇執(zhí)行兩次UPDATE語(yǔ)句,如下所示
    --條件1
    UPDATEPersonnel
    SETsalary = salary * 0.9
    WHEREsalary >= 5000;
    --條件2
    UPDATEPersonnel
    SETsalary = salary * 1.15
    WHEREsalary >= 2000 ANDsalary < 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è)功能的話,我們需要用到Case函數(shù)。代碼如下:
    UPDATEPersonnel
    SETsalary = CASEWHENsalary >= 5000
    THENsalary * 0.9
    WHENsalary >= 2000 ANDsalary < 4600
    THENsalary * 1.15
    ELSEsalary 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ù)的話,一切都變得簡(jiǎn)單多了。
    p_keycol_1col_2
    a1張三
    b2李四
    c3王五


    假設(shè)有如上數(shù)據(jù),需要把主鍵a 和b 相互交換。用Case函數(shù)來(lái)實(shí)現(xiàn)的話,代碼如下
    UPDATESomeTable
    SETp_key = CASEWHENp_key = 'a'
    THEN'b'
    WHENp_key = 'b'
    THEN'a'
    ELSEp_key END
    WHEREp_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í)候
    SELECTkeyCol,
    CASEWHENkeyCol IN( SELECTkeyCol FROMtbl_B )
    THEN'Matched'
    ELSE'Unmatched'ENDLabel
    FROMtbl_A;
    --使用EXISTS的時(shí)候
    SELECTkeyCol,
    CASEWHENEXISTS ( SELECT* FROMtbl_B
    WHEREtbl_A.keyCol = tbl_B.keyCol )
    THEN'Matched'
    ELSE'Unmatched'ENDLabel
    FROMtbl_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)
    1001經(jīng)濟(jì)學(xué)Y
    1002歷史學(xué)N
    2002歷史學(xué)N
    2003考古學(xué)Y
    2004計(jì)算機(jī)N
    3004計(jì)算機(jī)N
    4005化學(xué)N
    5006數(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的話,就沒(méi)有下面的麻煩事了,為了舉例子,還請(qǐng)多多包含)。
    現(xiàn)在我們要按照下面兩個(gè)條件對(duì)這個(gè)表進(jìn)行查詢(xún)
  • 只選修一門(mén)課程的人,返回那門(mén)課程的ID
  • 選修多門(mén)課程的人,返回所選的主課程ID

  • 簡(jiǎn)單的想法就是,執(zhí)行兩條不同的SQL語(yǔ)句進(jìn)行查詢(xún)。
    條件1
    --條件1:只選擇了一門(mén)課程的學(xué)生
    SELECTstd_id, MAX(class_id) ASmain_class
    FROMStudentclass
    GROUPBYstd_id
    HAVINGCOUNT(*) = 1;

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

    條件2
    --條件2:選擇多門(mén)課程的學(xué)生
    SELECTstd_id, class_id ASmain_class
    FROMStudentclass
    WHEREmain_class_flg = 'Y';

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

    如果使用Case函數(shù),我們只要一條SQL語(yǔ)句就可以解決問(wèn)題,具體如下所示
    SELECTstd_id,
    CASEWHENCOUNT(*) = 1 --只選擇一門(mén)課程的學(xué)生的情況
    THENMAX(class_id)
    ELSEMAX(CASEWHENmain_class_flg = 'Y'
    THENclass_id
    ELSENULLEND
    )
    ENDASmain_class
    FROMStudentclass
    GROUPBYstd_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ò)誤
    CASEcol_1
    WHEN1   THEN'Right'
    WHENNULLTHEN'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。 case的作用就是得到了一個(gè)返回值(Variant),或一個(gè)新的字段,這個(gè)值可以和普通值一樣做各種操作

    轉(zhuǎn)載于:https://www.cnblogs.com/dongzhiquan/archive/2009/04/13/1994905.html

    與50位技術(shù)專(zhuān)家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的SQL中条件和比较关键字Case的使用方法(case的结果就是得到了一个值)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。