select case when if 的一些用法

概述:
sql语句中的case语句与高级语言中的switch语句,是标准sql的语法,适用于一个条件判断有多种值的情况下分别执行不同的操作。

首先,让我们看一下CASE的语法。在一般的SELECT中,其语法格式如下:

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

# 向表中插入测试数据

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

数据表如下图:

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

实验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

 
分类: MySQL,SQL
标签: SQL

case...when...then if 用法的更多相关文章

  1. MySQL中case when的基本用法总结

    MySQL中case when的基本用法总结原创Backcanhave7 最后发布于2018-12-06 15:14:15 阅读数 439 收藏展开MySQL中的case when有用两种用法,官方文 ...

  2. Linux之shell脚本for、while、case语句的高级用法

    1.case语句的用法: [root@ELK-chaofeng test]# cat test3.sh #!/bin/bash while true ;do read -p "please ...

  3. case when then的用法

    用法一:等值判断,相当于switch CASE expression WHEN value1 THEN returnValue1 WHEN value2 THEN returnValue2 WHEN ...

  4. 数据库SQL中case when函数的用法

    Case具有两种格式,简单Case函数和Case搜索函数.这两种方式,可以实现相同的功能.简单Case函数的写法相对比较简洁,但是和Case搜索函数相比,功能方面会有些限制,比如写判断式. 简单Cas ...

  5. oracle case when 语句的用法详解

    1. CASE WHEN 表达式有两种形式 复制代码代码如下: --简单Case函数  CASE sex  WHEN '1' THEN '男'  WHEN '2' THEN '女'  ELSE '其他 ...

  6. sehll-011:case脚本的基本用法

    ##  注意判断的括号里的用法, 变量用双引号,且括号后面带空格.否则可能会有报错. #!/bin/bash # 我们可以认为1-3是三个不同的大脚本.我这里用简单的命令代替. echo " ...

  7. SQL Server中【case...end】的用法

    在SQL Server中 case...end 语句,一般有如下两种用法: 1.相当于C#中if...else,例: select CName,头衔=case when CLevel='A1' the ...

  8. case和decode的用法(行转列)

    创建了一张成绩表,如下图所示: 在oracle中,这两个函数我们都可以使用,代码及结果如下: decode用法: select Name,decode(Subject,'语文',1,'数学',2,'英 ...

  9. SQL 中case when then else 用法

    SQL如下: SELECT DISTINCTsy_haken_type,sy_sagyo_type,sy_kokyaku_cdFROm tbl_syukeiWHERE (sy_sagyo_ymd be ...

随机推荐

  1. [转]supervisor 安装、配置、常用命令

    原文: http://www.cnblogs.com/xueweihan/p/6195824.html ------------------------------------------------ ...

  2. MySql解压版使用

    1.解压 2.配置环境变量 3.新建空目录data,修改ini配置文件,修改basedir和datadir 4.管理员运行cmd,进入bin目录 5.mysql -install,如果提示错误,先my ...

  3. Gulp帮你自己主动搞定coffee和scss的compile

    今天继续说说gulp的watch,能够自己主动搞定非常多事情.不用每次都去敲命令了! 上次说到用gulp能够非常方便的进行css,js,html的压缩.而且能够对coffee和scss进行编译. cs ...

  4. Android 依据EditText搜索框ListView动态显示数据

    依据EditText搜索框ListView动态显示数据是依据需求来的,认为这之中涉及的东西可能比較的有意思,所以动手来写一写.希望对大家有点帮助. 首先.我们来分析下整个过程: 1.建立一个layou ...

  5. 用CSS3实现带有阴影效果和颜色渐变的按钮

    这里讲下如何利用css3里的两个新属性 box-shadow和transition来实现如下所示的带有阴影和颜色渐变效果的按钮(下面这个只是图片:本想直接在这个页面下嵌html的,,试了后发现有些cs ...

  6. libcurl实现解析(3) - libcurl对select的使用

    1.前言 在本系列的前一篇文章中.介绍了libcurl对poll()的使用. 參考"libcurl原理解析(2) - libcurl对poll的使用". 本篇文章主要分析curl_ ...

  7. luogu1197 [JSOI2008]星球大战

    题目大意 有一个无向图,每次删除一个节点,求删除后图中连通块的个数.(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中) 题解 连通块?用并查集可以找到一个连通块,但是 ...

  8. ambarella H2 添加文件到ext4文件系统

    方法1: ambarella/rootfs目录下有skeleton(骨架)目录,此目录下就是文件系统的各个目录, [root@jz4775dev]# ls skeleton/ bin debug de ...

  9. Elias-Fano编码算法——倒排索引压缩用,本质上就是桶排序数据结构思路

    Elias-Fano编码过程如下:把一组整数的最低l位连接在一起,同时把高位以严格单调增的排序划分为桶. Example: 2, 3, 5, 7, 11, 13, 24 Count in unary ...

  10. 动态规划---状压dp2

    今天模拟,状压dp又没写出来...还是不会啊,所以今天搞一下这个状压dp.这里有一道状压dp的板子题: Corn FieldsCorn Fields 就是一道很简单的状压裸题,但是要每次用一个二进制数 ...