如下这张表,包含id和name两列,其中id是主键,name允许为空,存在两条记录,一条是(id=1,name='a'),另一条是(id=2,name=''),

SQL> create table emp(id number primary key, name varchar2(25));
Table created.SQL> select * from emp;ID  NAME
---- -------1  a2

我的问题是,给定具体的id和name值作为检索条件的前提下,如何写出一条通用的SQL同时满足name为空和不为空的场景?

可能很容易想到这条SQL,

SQL> select * from emp where id=:id and name=:name;

如果针对(id=1,name='a')的记录,这条SQL是对的,

SQL> variable id number
SQL> variable name varchar2(25)
SQL> exec :id := 1; :name := 'a';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and name=:name;                   ID  NAME
---- -------1  a

但是针对(id=2,name='')的记录,这条SQL是错的,原因就是在Oracle中null=null返回的是false,判断空值,需要使用is null或者is not null,

SQL> exec :id := 2; :name := '';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and name=:name;
no rows selected

因此按照理解,改写SQL,此时能同时满足这两种场景,如果:name参数不为空,则会使用name=:name条件,如果:name参数为空,则会使用name is null and :name is null条件,限定检索字段name为空,同时参数:name为空,

SQL> exec :id := 1; :name := 'a';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and (name=:name or (name is null and :name is null));ID  NAME
---- -------1  aSQL> exec :id := 2; :name := '';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and (name=:name or (name is null and :name is null));ID  NAME
---- -------2

其实,Tom大叔和Darl的经典著作《Oracle编程艺术-深入理解数据库体系结构》中提到了一种更为简单的操作,使用decode函数,

如果decode函数中expr和search相等,则Oracle返回result,如果expr和search不等,则Oracle返回default,若未指定default,则返回空值。

改写SQL,我们看到,无论是(id=1,name='a')的记录,还是(id=2,name ='')的记录,都可以通过该语句得到,

SQL> exec :id := 1; :name := 'a';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and decode(name, :name, 1)=1;ID   NAME
----- -------1   aSQL> exec :id := 2; :name := '';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and decode(name, :name, 1)=1;ID   NAME
----- -------2

他的精髓就在于,decode函数中,Oracle会认为两个空值是等价的,官方文档的介绍如下,这就解决了(null=null)问题,

In a DECODE function, Oracle considers two nulls to be equivalent. If expr is null, then Oracle returns the result of the first search that is also null.

但是要注意的是,为这条SQL选择索引,只能对id列创建,不能对decode函数创建,因为Oracle不能基于未知的用户输入创建索引数据,

SQL> select * from emp where id=:id and decode(name, :name, 1)=1;

近期热文:

《公众号600篇文章分类和索引》

《Oracle ACE,一段不可思议的旅程》

《Oracle 19c之RPM安装》

《应用执行慢的问题排查路径》

《ACOUG年会感想》

《千万级表数据更新的需求》

《探寻大表删除字段慢的原因》

《一次Oracle bug的故障排查过程思考》

《新增字段的一点一滴技巧》

《对recursive calls的深刻理解》

《《Oracle Concept》第三章 - 12》

《一次惊心动魄的问题排查》

《英超梦幻之行》

《藤子不二雄博物馆之行》

《传控Tiki-Taka战术解惑》

decode函数的妙用相关推荐

  1. decode函数_decode函数的妙用网友的两个问题解答

    <decode函数的妙用>这篇文章中,提到两种写法, SQL> select * from emp where id=:id and (name=:name or (name is ...

  2. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  3. mysql sql decode函数用法_oracle中的decode的使用介绍

    含义解释: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下: IF 条件=值1 THEN RETURN(翻译值1) ELSIF 条件=值2 THE ...

  4. oracle decode一个值对应多个值,如何使用Oracle的Decode函数进行多值判断

    Decode函数的语法结构如下: decode (expression, search_1, result_1) decode (expression, search_1, result_1, sea ...

  5. 先随机后排序的oracle,Oracle用decode函数或CASE-WHEN实现自定义排序

    Oracle用decode函数或CASE-WHEN实现自定义排序 1 问题 对SQL排序,只要在order by后面加字段就可以了,可以通过加desc或asc来选择降序或升序.但排序规则是默认的,数字 ...

  6. SQL中 decode()函数简介

    今天看别人的SQL时看这里面还有decode()函数,以前从来没接触到,上网查了一下,还挺好用的一个函数,写下来希望对朋友们有帮助哈! decode()函数简介: 主要作用:将查询结果翻译成其他值(即 ...

  7. decode函数python在哪里_Python基础知识——encode和decode函数

    以前我们介绍过,Python2.x中默认的编码的基础类型是unicode编码的类型,在Python3.x才转化为基于unicode的字符串. 那么我们在Python2.x的学习中就会遇到各种各样的编码 ...

  8. oracle中创建函数行变列,oracle decode 函数实现行转列

    用decode函数,或者case when实现行转列 Oracle ----创建测试表create table student_score( name varchar2(20), subject va ...

  9. python中的encode()和decode()函数

    对于很多人来说,python的中字符转码是一件很头疼的事情,本来期望结果输出的是中文,结果来一段像这样\xe4\xbd\xa0\xe5\xa5\xbd像是乱码的字符串. 由于学python没多久,昨天 ...

最新文章

  1. java 微网站_java架构之路-(微服务专题)初步认识微服务与nacos初步搭建
  2. 小学生在家自学python_小学生都能学会的python(函数)
  3. input点击链接另一个页面,各种操作。
  4. java8中stream中的任务拆分
  5. 服务器运维应该报什么专业,数据中心基础设施运维人员应该掌握哪些专业技能?...
  6. TYVJ 4354 多重背包二进制优化
  7. 2、http网络编程——libcurl的使用
  8. JavaScript 设计模式之模板方法模式
  9. 去百度还是去创新工厂? 信开复还是信彦宏?
  10. 没用东西全部清掉_如何把电脑上无用的东西清理掉,在哪下载
  11. OFDM专题之如何计算OFDM一个符号的功率,功率谱密度
  12. 往事如烟 - 父亲母亲的居木子豆腐
  13. 计算机不能再U盘新建文件夹,如何让你的U盘永不中毒?新建一个文件夹就搞定!-u盘文件夹变成exe...
  14. File-backed Storage
  15. python上进行日期的儒略日换算
  16. 计算机网络 路由器的端口ip,给路由器的一个接口上配置两个IP地址
  17. #455 科技乱炖:看完《流浪地球2》,我们为行星发动机设计了网络架构
  18. LVM Linear vs Striped Logical Volumes
  19. 美团点评2020校招笔试练习
  20. [转载]AIX 常见问题整理

热门文章

  1. c语言编程 测试姓名缘分,姓名配对两人爱情结果 爱情测试游戏
  2. Android调用相机拍照录视频录音以及存储,7.0以上及以下都可使用。
  3. 腾讯将在印度推出UPI支付应用 与Paytm和Google Pay展开竞争
  4. 如何在VMware虚拟机间建立共享磁盘?
  5. Citavi及DBServer安装使用
  6. Java知识点——类、超类和子类
  7. java基础:map遍历使用;java使用 Patten 和Matches 进行正则匹配;后端传到前端展示图片三种情况,并保存到手机;
  8. 大小写 数据库 达梦_达梦数据库,大小写敏感这个参数怎么设置
  9. 嗨,躺在床上刷剧的你!
  10. 短视频APP源码隐藏桌面图标