select case when if 的一些用法

概述:
sql語句中的case語句與高級語言中的switch語句,是標準sql的語法,適用於一個條件判斷有多種值的狀況下分別執行不一樣的操做。mysql

首先,讓咱們看一下CASE的語法。在通常的SELECT中,其語法格式以下:sql

 CASE   <單值表達式>
        WHEN <表達式值> THEN <SQL語句或者返回值>
        WHEN <表達式值> THEN <SQL語句或者返回值>
        ...
        WHEN <表達式值> THEN <SQL語句或者返回值>
        ELSE <SQL語句或者返回值>
 END數據庫

★ 第一部分函數

# 建立一個用戶表性能

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測試


# 向表中插入測試數據spa

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','北京')3d

數據表以下圖:blog

------------------------------------------------------------------------------------------排序

實驗1.1:將用戶性別用文字直觀顯示

1.簡單Case函數寫法(注意sex的位置)

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

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

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



總結:簡單Case函數寫法只適合相等條件判斷,不能用於大於、小於及不等於的判斷,
        Case搜索函數寫法適合複雜條件判斷:可用於大於、小於及不等於的判斷。
------------------------------------------------------------------------------------------

實驗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



總結:用臨時生成的字段是能夠排序的,MySQL查詢流程:先對錶數據查詢,查出數據後再排序顯示。
------------------------------------------------------------------------------------------

實驗1.3:將用戶年齡用文字直觀顯示(涉及數值範圍判斷,只能使用「Case搜索函數」寫法),以下:

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

------------------------------------------------------------------------------------------
實驗1.4:綜合上面兩實驗
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


------------------------------------------------------------------------------------------

實驗1.5:將區域分組,統計華北、華南分別的註冊人數
select count(*),(CASE province WHEN '北京' THEN '華北' WHEN '天津' THEN '華北' WHEN '河北' THEN '華北' WHEN '廣東' THEN '華南' WHEN '湖南' THEN '華南' END) as area
from user
group by area



總結:一樣道理,臨時生成的字段 area 是能夠在查詢結束後,用來作排序或分組的。

==========================================================================================

★ 第二部分

# 建立數據表

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


# 插入測試數據

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')

 


實驗2.1:查詢dj_zt表狀態值(zt)爲'07'或'11',當條件爲 qylx_dm = '03' 的全部記錄數。

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')



結果:A、B兩組耗費的代價同樣的,相比較B的寫法簡潔,平局。

------------------------------------------------------------------------------------------

實驗2.2: 分別查詢dj_zt表狀態爲'07'和'11'且qylx_dm = '03'的全部記錄數。

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'



結果:B組代價明顯高出A組不少,執行的效率比較低。


總結:CASE 和 IF的區別:
·在高級語言中,CASE的能夠用IF來替代,可是在SQL中不行。
·CASE是SQL標準定義的,IF是數據庫系統的擴展。
·CASE能夠用於SQL語句和SQL存儲過程、觸發器,IF只能用於存儲過程和觸發器。
·在SQL過程和觸發器中,用IF替代CASE代價都至關的高,至關的麻煩,難以實現。

經過上面幾組實例能夠看出,應用CASE語句可讓SQL變得簡潔高效,從而大大提升了執行效率。並且,CASE的使用通常不會引發性能(相比沒有用CASE的語句)低下,反而增長了操做的靈活性


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


★ 第三部分 IF語句的用法

▶ IF(expr1,expr2,expr3)

規則:若是 expr1 是TRUE,則返回expr2, 不然返回expr3。

IF() 的返回值爲數字值或字符串值,具體狀況視其所在語境而定。

實驗3.1:以下:

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



總結: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() 函數的結果類型 爲非NULL表達式的結果類型。
expr1 做爲一個整數值進行計算,就是說,假如你正在驗證浮點值或字符串值, 那麼應該使用比較運算進行檢驗。

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

mysql> SELECT IF(0.1<>0,1,0);
-> 1
 
在所示的第一個例子中,IF(0.1)的返回值爲0,緣由是 0.1 被轉化爲整數值,從而引發一個對 IF(0)的檢驗。這或許不是你想要的狀況。在第二個例子中,比較檢驗了原始浮點值,目的是爲了瞭解是否其爲非零值。比較結果使用整數。

------------------------------------------------------------------------------------------

▶ IFNULL(expr1,expr2)

規則:假如 expr1 不爲 NULL,就返回 expr1,不然返回 expr2。
         IFNULL()的返回值是數字或是字符串,具體狀況取決於其所使用的語境。

實驗3.2:若是字段bs爲空就返回字段zt的值

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




實驗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)的默認結果值爲兩個表達式中更加「通用」的一個,順序爲STRING、 REAL或 INTEGER。假設一個基於表達式的表的狀況, 或MySQL必須在內存儲器中儲存一個臨時表中IFNULL()的返回值:
 
------------------------------------------------------------------------------------------

▶ NULLIF(expr1,expr2)

規則:若是 expr1 = expr2 成立,那麼返回值爲NULL,不然返回值爲 expr1。
        這和CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END相同。

實驗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

注意,若是參數不相等,則 MySQL 兩次求得的值爲 expr1

相關文章
相關標籤/搜索