select case when if 的一些用法【轉(zhuǎn)載】

概述:
sql語句中的case語句與高級語言中的switch語句更卒,是標(biāo)準(zhǔn)sql的語法,適用于一個條件判斷有多種值的情況下分別執(zhí)行不同的操作稚照。
首先蹂空,讓我們看一下CASE的語法。在一般的SELECT中果录,其語法格式如下:

 CASE   <單值表達(dá)式>
        WHEN <表達(dá)式值> THEN <SQL語句或者返回值>
        WHEN <表達(dá)式值> THEN <SQL語句或者返回值>
        ...
        WHEN <表達(dá)式值> THEN <SQL語句或者返回值>
        ELSE <SQL語句或者返回值>
 END

★ 第一部分

創(chuàng)建一個用戶表

CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL auto_increment, 
`sex` tinyint(1) default 1 COMMENT '性別:0女上枕;1男;2保密',
`age` int(3) default 1 COMMENT '年齡',
`province` char(254) default NULL COMMENT '所在省份',
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

向表中插入測試數(shù)據(jù)

INSERT INTO user(sex,age,province) VALUES
('1','22','北京'),
('0','25','廣東'),
('0','56','天津'),
('1','14','北京'),
('0','36','廣東'),
('1','68','湖南'),
('1','45','北京'),
('1','17','河北'),
('2','33','天津'),
('1','27','湖南'),
('1','29','北京'),
('2','70','廣東'),
('0','24','北京')

數(shù)據(jù)表如下圖:



實(shí)驗(yàn)1.1:將用戶性別用文字直觀顯示
1.簡單Case函數(shù)寫法(注意sex的位置)

select *,(CASE sex WHEN '1' THEN '男' WHEN '0' THEN '女' ELSE '保密' END) as sex_text
from user

2.Case搜索函數(shù)寫法(注意sex的位置【推薦】)

select *,(CASE WHEN sex='1' THEN '男' WHEN sex='0' THEN '女' ELSE '保密' END) as sex_text
from user

總結(jié):簡單Case函數(shù)寫法只適合相等條件判斷弱恒,不能用于大于辨萍、小于及不等于的判斷,
Case搜索函數(shù)寫法適合復(fù)雜條件判斷:可用于大于返弹、小于及不等于的判斷锈玉。


實(shí)驗(yàn)1.2:將用戶性別用文字直觀顯示:0女;1男义起;2保密拉背;并按性別顯示排序

select *,(CASE WHEN sex='1' THEN '男' WHEN sex='0' THEN '女' ELSE '保密' END) as sex_text
from user
order by sex_text DESC

總結(jié):用臨時生成的字段是可以排序的,MySQL查詢流程:先對表數(shù)據(jù)查詢默终,查出數(shù)據(jù)后再排序顯示椅棺。


實(shí)驗(yàn)1.3:將用戶年齡用文字直觀顯示(涉及數(shù)值范圍判斷,只能使用“Case搜索函數(shù)”寫法)齐蔽,如下:

select *,(CASE WHEN age>=60 THEN '老年' WHEN age<60 AND age>=30 THEN '中年' WHEN age<30 AND age>=18 THEN '青年' ELSE '未成年' END) as age_text
from user

實(shí)驗(yàn)1.4:綜合上面兩實(shí)驗(yàn)

select *,
(CASE WHEN sex='1' THEN '男' WHEN sex='0' THEN '女' ELSE '保密' END) as sex_text,
(CASE WHEN age>=60 THEN '老年' WHEN age<60 AND age>=30 THEN '中年' WHEN age<30 AND age>=18 THEN '青年' ELSE '未成年' END) as age_text
from user

實(shí)驗(yàn)1.5:將區(qū)域分組两疚,統(tǒng)計華北、華南分別的注冊人數(shù)

select count(*),(CASE province WHEN '北京' THEN '華北' WHEN '天津' THEN '華北' WHEN '河北' THEN '華北' WHEN '廣東' THEN '華南' WHEN '湖南' THEN '華南' END) as area
from user
group by area

總結(jié):同樣道理肴熏,臨時生成的字段 area 是可以在查詢結(jié)束后鬼雀,用來做排序或分組的顷窒。
==========================================================================================
★ 第二部分

創(chuàng)建數(shù)據(jù)表

CREATE TABLE `dj_zt` (
`id` int(10) unsigned NOT NULL auto_increment, 
`zt` char(254) default NULL,
`bs` char(254) default NULL,
`qylx_dm` char(254) default NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

插入測試數(shù)據(jù)

INSERT INTO dj_zt(zt, bs, qylx_dm) VALUES
('01','a','01'),
('02','b','02'),
('03','c','03'),
('11','d','03'),
('03',null,'04'),
('07','f','03'),
('12','g','02'),
('07','h','03'),
('11','i','03'),
('07','j','03'),
('11','k','04')

實(shí)驗(yàn)2.1:查詢dj_zt表狀態(tài)值(zt)為'07'或'11'蛙吏,當(dāng)條件為 qylx_dm = '03' 的所有記錄數(shù)源哩。
A:用CASE語句

select count(CASE a.zt WHEN '07' THEN a.bs END) + count(CASE a.zt WHEN '11' THEN a.bs END) as num
from dj_zt a
where a.qylx_dm = '03'

B:不用CASE語句

select count(*)
from dj_zt a
where a.qylx_dm = '03' and a.zt in ('07', '11')

結(jié)果:A、B兩組耗費(fèi)的代價一樣的鸦做,相比較B的寫法簡潔励烦,平局。


實(shí)驗(yàn)2.2: 分別查詢dj_zt表狀態(tài)為'07'和'11'且qylx_dm = '03'的所有記錄數(shù)泼诱。
A:用CASE語句

select count(CASE a.zt WHEN '07' THEN a.bs END) as num1,count(CASE a.zt WHEN '11' THEN a.bs END) as num2
from dj_zt a
where a.qylx_dm = '03'

B:不用CASE語句(寫了兩條語句坛掠,掃描表兩遍,效率明顯低下)

select count(*)
from dj_zt a
where a.qylx_dm = '03' and a.zt='07'
select count(*)
from dj_zt a
where a.qylx_dm = '03' and a.zt='11'

結(jié)果:B組代價明顯高出A組很多,執(zhí)行的效率比較低治筒。

總結(jié):CASE 和 IF的區(qū)別:
·在高級語言中屉栓,CASE的可以用IF來替代,但是在SQL中不行耸袜。
·CASE是SQL標(biāo)準(zhǔn)定義的友多,IF是數(shù)據(jù)庫系統(tǒng)的擴(kuò)展。
·CASE可以用于SQL語句和SQL存儲過程堤框、觸發(fā)器域滥,IF只能用于存儲過程和觸發(fā)器。
·在SQL過程和觸發(fā)器中蜈抓,用IF替代CASE代價都相當(dāng)?shù)母咂舸拢喈?dāng)?shù)穆闊y以實(shí)現(xiàn)沟使。

通過上面幾組實(shí)例可以看出委可,應(yīng)用CASE語句可以讓SQL變得簡潔高效,從而大大提高了執(zhí)行效率腊嗡。而且撤缴,CASE的使用一般不會引起性能(相比沒有用CASE的語句)低下,反而增加了操作的靈活性

◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

★ 第三部分 IF語句的用法
? IF(expr1,expr2,expr3)

? IF(expr1,expr2,expr3)

規(guī)則:如果 expr1 是TRUE叽唱,則返回expr2屈呕, 否則返回expr3。

IF() 的返回值為數(shù)字值或字符串值棺亭,具體情況視其所在語境而定虎眨。

實(shí)驗(yàn)3.1:如下:

select *,IF(sex='1','男','非男') as sex_text
from user

總結(jié):IF不像CASE那樣可以多條件判斷,IF只能判斷“真”镶摘、“假”嗽桩;

mysql> SELECT IF(1>2,2,3);
-> 3
 
mysql> SELECT IF(1<2,'yes ','no');
-> 'yes'

mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
-> 'no'

如果expr2 或expr3中只有一個明確是 NULL,則IF() 函數(shù)的結(jié)果類型 為非NULL表達(dá)式的結(jié)果類型凄敢。
expr1 作為一個整數(shù)值進(jìn)行計算碌冶,就是說,假如你正在驗(yàn)證浮點(diǎn)值或字符串值涝缝, 那么應(yīng)該使用比較運(yùn)算進(jìn)行檢驗(yàn)扑庞。

mysql> SELECT IF(0.1,1,0);
-> 0

mysql> SELECT IF(0.1<>0,1,0);
-> 1

在所示的第一個例子中譬重,IF(0.1)的返回值為0,原因是 0.1 被轉(zhuǎn)化為整數(shù)值罐氨,從而引起一個對 IF(0)的檢驗(yàn)臀规。這或許不是你想要的情況。在第二個例子中栅隐,比較檢驗(yàn)了原始浮點(diǎn)值塔嬉,目的是為了了解是否其為非零值。比較結(jié)果使用整數(shù)租悄。


? IFNULL(expr1,expr2)

規(guī)則:假如 expr1 不為 NULL谨究,就返回 expr1,否則返回 expr2泣棋。
IFNULL()的返回值是數(shù)字或是字符串记盒,具體情況取決于其所使用的語境。

實(shí)驗(yàn)3.2:如果字段bs為空就返回字段zt的值

select *,IFNULL(bs,zt)
from dj_zt
where id in (5,6,12)

實(shí)驗(yàn)3.3:如果字段bs為空就返回'ZZX'

select *,IFNULL(bs,'ZZX')
from dj_zt
where id in (5,6,12)
mysql> SELECT IFNULL(1,0);
-> 1
 
mysql> SELECT IFNULL(NULL,10);
-> 10
 
mysql> SELECT IFNULL(1/0,10);
-> 10

mysql> SELECT IFNULL(1/0,'yes');
-> 'yes'

IFNULL(expr1,expr2)的默認(rèn)結(jié)果值為兩個表達(dá)式中更加“通用”的一個外傅,順序?yàn)镾TRING纪吮、 REAL或 INTEGER。假設(shè)一個基于表達(dá)式的表的情況萎胰, 或MySQL必須在內(nèi)存儲器中儲存一個臨時表中IFNULL()的返回值:


? NULLIF(expr1,expr2)

規(guī)則:如果 expr1 = expr2 成立碾盟,那么返回值為NULL,否則返回值為 expr1技竟。
這和CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END相同冰肴。

實(shí)驗(yàn)3.4:如果字段zt 與 字段qylx_dm有相等的值,就返回空榔组,否則返回zt

select *,NULLIF(zt,qylx_dm)
from dj_zt
mysql> SELECT NULLIF(1,1);
-> NULL

mysql> SELECT NULLIF(1,2);
-> 1

注意熙尉,如果參數(shù)不相等,則 MySQL 兩次求得的值為 expr1

轉(zhuǎn)載自:https://www.cnblogs.com/martinzhang/p/3220595.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搓扯,一起剝皮案震驚了整個濱河市检痰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锨推,老刑警劉巖铅歼,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異换可,居然都是意外死亡椎椰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進(jìn)店門沾鳄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慨飘,“玉大人,你說我怎么就攤上這事译荞∪康模” “怎么了休弃?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長堤瘤。 經(jīng)常有香客問我凉当,道長洽损,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任赖淤,我火速辦了婚禮医增,結(jié)果婚禮上慎皱,老公的妹妹穿的比我還像新娘。我一直安慰自己叶骨,他們只是感情好茫多,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著忽刽,像睡著了一般天揖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跪帝,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天今膊,我揣著相機(jī)與錄音,去河邊找鬼伞剑。 笑死斑唬,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的黎泣。 我是一名探鬼主播恕刘,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抒倚!你這毒婦竟也來了褐着?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤托呕,失蹤者是張志新(化名)和其女友劉穎献起,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镣陕,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谴餐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呆抑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岂嗓。...
    茶點(diǎn)故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鹊碍,靈堂內(nèi)的尸體忽然破棺而出厌殉,到底是詐尸還是另有隱情食绿,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布公罕,位于F島的核電站器紧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏楼眷。R本人自食惡果不足惜铲汪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罐柳。 院中可真熱鬧掌腰,春花似錦、人聲如沸张吉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肮蛹。三九已至勺择,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伦忠,已是汗流浹背省核。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缓苛,地道東北人芳撒。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像未桥,于是被迫代替她去往敵國和親笔刹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評論 2 361

推薦閱讀更多精彩內(nèi)容