分享好友 数据库首页 频道列表

Oracle数据库中对null值的排序及mull与空字符串的区别

Oracle教程  2016-05-18 12:480

order by排序之null值处理方法
在对业务数据排序时候,发现有些字段的记录是null值,这时排序便出现了有违我们使用习惯的数据大小顺序问题。在Oracle中规定,在Order by排序时缺省认为null是最大值,所以如果是ASC升序则被排在最后,而DESC降序则排在最前。所以,为何分析数据的直观性方便性,我们需要对null的记录值进行相应处理。
这是四种oracle排序中NULL值处理的方法:
1、使用nvl函数
语法:Nvl(expr1, expr2)
    若EXPR1是NULL,則返回EXPR2,否則返回EXPR1.

  SELECT NAME,NVL(TO_CHAR(COMM),'NOT APPLICATION') FROM TABLE1;

nvl函数可以在输入参数为空时转换为一特定值,如
nvl(person_name,“未知”)表示若person_name字段值为空时返回“未知”,如不为空则返回person_name的字段值。
通过这个函数可以定制null的排序位置。
2、使用decode函数
 
decode函数比nvl函数更强大,同样它也可以将输入参数为空时转换为一特定值,如
decode(person_name,null,“未知”, person_name)表示当person_name为空时返回“未知”,如不为空则返回person_name的字段值。
通过此函数也可以定制null的排序位置。

3、使用nulls first 或者nulls last 语法,最简单常用的方法。

Nulls first和nulls last是Oracle Order by支持的语法

(1)若Order by 中指定了表达式Nulls first则表示null值的记录将排在最前(不管是asc 还是 desc)

(2)若Order by 中指定了表达式Nulls last则表示null值的记录将排在最后 (不管是asc 还是 desc)

使用方法举例如下:
将nulls始终放在最前:

select * from tbl order by field nulls first

将nulls始终放在最后:

select * from tbl order by field desc nulls last

4、使用case 语法
 
Case语法是Oracle 9i后开始支持的,是一个比较灵活的语法,同样在排序中也可以应用
如:

select *
 from students
 order by (case person_name
      when null then
       '未知'
      else
       person_name
     end)

表示在person_name字段值为空时返回'未知',如果不为空则返回person_name
通过case语法同样可以定制null的排序位置。
 
项目实例:

  !defined('PATH_ADMIN') && exit('Forbidden'); 
class mod_gcdownload 
{ 
  public static function get_gcdownload_datalist($start = 0,$rowsperpage = PAGE_ROWS, $datestart = '',$dateend = '',$ver = '',$coopid = '',$subcoopid = '',$sortfield = '', $sorttype = '', $pid = 123456789, $plat = 'abcdefg'){ 
    $sql = ''; 
    $condition = empty($datestart)  " WHERE 1=1 " : " WHERE t.statistics_date >= '$datestart' AND t.statistics_date <= '$dateend'"; 
    if($ver) 
    { 
      $condition .= " AND t.edition='$ver'"; 
    } 
    if($coopid) 
    { 
      $condition .= " AND t.suco_coopid=$coopid"; 
    } 
    if($subcoopid) 
    { 
      $condition .= " AND t.suco_subcoopid=$subcoopid"; 
    } 
    if($sortfield && $sorttype){ 
      $condition .= " ORDER BY t.{$sortfield} {$sorttype} NULLS LAST"; 
    }elseif($sortfield){ 
      $condition .= " ORDER BY t.{$sortfield} desc NULLS LAST"; 
    }else{ 
      $condition .= " ORDER BY t.statistics_date desc NULLS LAST"; 
    } 
    $finish = $start + $rowsperpage; 
    $joinsqlcollection = "(SELECT tc.coop_name, tsc.suco_name, tsc.suco_coopid,tsc.suco_subcoopid, s.edition, s.new_user, d.one_user, d.three_user, d.seven_user, s.statistics_date FROM (((pdt_stat_newuser_{$pid}_{$plat} s LEFT JOIN pdt_days_dl_remain_{$pid}_{$plat} d ON s.statistics_date=d.new_date AND s.subcoopid=d.subcoopid AND s.edition=d.edition )LEFT JOIN tbl_subcooperator@JTUSER1.NET@JTINFO tsc ON s.subcoopid=tsc.suco_subcoopid) LEFT JOIN tbl_cooperator@JTUSER1.NET@JTINFO tc ON tsc.suco_coopid=tc.coop_id))"; 
    $sql = "SELECT * FROM (SELECT tb_A.*, ROWNUM AS rn FROM (SELECT t.* FROM $joinsqlcollection t {$condition} ) tb_A WHERE ROWNUM <= {$finish} ) tb_B WHERE tb_B.rn>{$start} "; 
    $countsql = "SELECT COUNT(*) AS totalrows, SUM(t.new_user) AS totalnewusr,SUM(t.one_user) AS totaloneusr,SUM(t.three_user) AS totalthreeusr,SUM(t.seven_user) AS totalsevenusr FROM $joinsqlcollection t {$condition} "; 
    $db = oralceinit(1); 
    $stidquery = $db->query($sql,false); 
    $output = array(); 
    while($row = $db->FetchArray($stidquery, $skip = 0, $maxrows = -1)) 
    {   
      $output['data'][] = array_change_key_case($row,CASE_LOWER); 
    } 
    $count_stidquery = $db->query($countsql,false); 
    $row = $db->FetchArray($count_stidquery, $skip = 0, $maxrows = -1); 
    $output['total']= array_change_key_case($row,CASE_LOWER); 
    //echo "<br />".($sql)."<br />"; 
    return $output;  
   
  } 
 
} 

Null与空字符串' '的区别
含义解释:
问:什么是NULL?
答:在我们不知道具体有什么数据的时候,也即未知,可以用NULL,我们称它为空,ORACLE中,含有空值的表列长度为零。
ORACLE允许任何一种数据类型的字段为空,除了以下两种情况:
1、主键字段(primary key),
2、定义时已经加了NOT NULL限制条件的字段
说明:
1、等价于没有任何值、是未知数。
2、NULL与0、空字符串、空格都不同。
3、对空值做加、减、乘、除等运算操作,结果仍为空。
4、NULL的处理使用NVL函数。
5、比较时使用关键字用“is null”和“is not null”。
6、空值不能被索引,所以查询时有些符合条件的数据可能查不出来,count(*)中,用nvl(列名,0)处理后再查。
7、排序时比其他数据都大(索引默认是降序排列,小→大),所以NULL值总是排在最后。
使用方法:

SQL> select 1 from dual where null=null; 

没有查到记录

SQL> select 1 from dual where null=''; 

没有查到记录

SQL> select 1 from dual where ''=''; 

没有查到记录

SQL> select 1 from dual where null is null; 
1 
--------- 
1 

SQL> select 1 from dual where nvl(null,0)=nvl(null,0); 

1 
--------- 
1 

对空值做加、减、乘、除等运算操作,结果仍为空。

SQL> select 1+null from dual; 
SQL> select 1-null from dual; 
SQL> select 1*null from dual; 
SQL> select 1/null from dual; 

查询到一个记录.
注:这个记录就是SQL语句中的那个null
设置某些列为空值

update table1 set 列1=NULL where 列1 is not null; 

现有一个商品销售表sale,表结构为:

month    char(6)      --月份 
sell    number(10,2)   --月销售金额 
create table sale (month char(6),sell number); 
insert into sale values('200001',1000); 
insert into sale values('200002',1100); 
insert into sale values('200003',1200); 
insert into sale values('200004',1300); 
insert into sale values('200005',1400); 
insert into sale values('200006',1500); 
insert into sale values('200007',1600); 
insert into sale values('200101',1100); 
insert into sale values('200202',1200); 
insert into sale values('200301',1300); 
insert into sale values('200008',1000); 
insert into sale(month) values('200009');(注意:这条记录的sell值为空) 
commit; 

共输入12条记录

SQL> select * from sale where sell like '%'; 
MONTH SELL 
------ --------- 
200001 1000 
200002 1100 
200003 1200 
200004 1300 
200005 1400 
200006 1500 
200007 1600 
200101 1100 
200202 1200 
200301 1300 
200008 1000 

查询到11记录.
结果说明:
查询结果说明此SQL语句查询不出列值为NULL的字段
此时需对字段为NULL的情况另外处理。

SQL> select * from sale where sell like '%' or sell is null; 
SQL> select * from sale where nvl(sell,0) like '%'; 
MONTH SELL 
------ --------- 
200001 1000 
200002 1100 
200003 1200 
200004 1300 
200005 1400 
200006 1500 
200007 1600 
200101 1100 
200202 1200 
200301 1300 
200008 1000 
200009 

查询到12记录.
Oracle的空值就是这么的用法,我们最好熟悉它的约定,以防查出的结果不正确。

但对于char 和varchar2类型的数据库字段中的null和空字符串是否有区别呢?
作一个测试:

create table test (a char(5),b char(5)); 
SQL> insert into test(a,b) values('1','1'); 
SQL> insert into test(a,b) values('2','2'); 
SQL> insert into test(a,b) values('3','');--按照上面的解释,b字段有值的 
SQL> insert into test(a) values('4'); 
SQL> select * from test; 
A B 
---------- ---------- 
1 1 
2 2 
3 
4 
SQL> select * from test where b='';

 ----按照上面的解释,应该有一条记录,但实际上没有记录
未选定行

SQL> select * from test where b is null; 

----按照上面的解释,应该有一跳记录,但实际上有两条记录。

A B 
---------- ---------- 
3 
4 
SQL>update table test set b='' where a='2'; 
SQL> select * from test where b=''; 

未选定行

SQL> select * from test where b is null; 
A B 
---------- ---------- 
2 
3 
4 

测试结果说明,对char和varchar2字段来说,''就是null;但对于where 条件后的'' 不是null。
对于缺省值,也是一样的!

查看更多关于【Oracle教程】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
去重复的sql(Oracle) 去重复的英文
1.利用group by 去重复2.可以利用下面的sql去重复,如下  1) select id,name,sex from (select a.*,row_number() over(partition by a.id,a.set order by name) su from test a ) where su=1  2)select id,name,sex from (select a.*,row_number() over(p

0评论2023-02-10893

Oracle SQL七次提速技巧
以下SQL执行时间按序号递减。1,动态SQL,没有绑定变量,每次执行都做硬解析操作,占用较大的共享池空间,若共享池空间不足,会导致其他SQL语句的解析信息被挤出共享池。create or replace procedure proc1as beginfor i in 1..100000 loop    execute imme

0评论2023-02-10755

SQL ORACLE case when函数用法
case when 用法(1)简单case函数:格式:  case 列名   when 条件值1 then 选项1  when 条件值1 then 选项2......  else 默认值 end例如:  select   case job_level  when '1' then '1111'  when '2' then '2222'   when '3' then '3333

0评论2023-02-10564

Oracle迁移到MySQL性能下降的注意点 oracle数据库迁移需要注意的问题
背景:最近有较多的客户系统由原来由Oracle改造到MySQL后出现了性能问题CPU 100%,或是后台的CRM系统复杂SQL在业务高峰的时候出现堆积导致业务故障。在我的记忆里面淘宝最初从Oracle迁移到MySQL期间也遇到了很多SQL的性能问题,记忆最为深刻的子查询,当初的

0评论2023-02-10580

ORACLE中通过SQL语句(alter table)来增加、删除、修改字段
1.添加字段:alter table  表名  add (字段  字段类型)  [ default  '输入默认值']  [null/not null]  ;2.添加备注:comment on column  库名.表名.字段名 is  '输入的备注';  如: 我要在ers_data库中  test表 document_type字段添加备注  comm

0评论2023-02-10584

MySQL与Oracle 差异比较之六触发器
触发器编号类别ORACLEMYSQL注释1创建触发器语句不同create or replace trigger TG_ES_FAC_UNIT  before insert or update or delete on ES_FAC_UNIT  for each rowcreate trigger `hs_esbs`.`TG_INSERT_ES_FAC_UNIT` BEFORE INSERT on `hs_esbs`.`es_fac_u

0评论2023-02-10914

Oracle的HINT可以强制指定SQL的执行计划,比如选择索引、表的连接顺序以及表的连接方式等等。(转)
在Oracle中查看所有的表: select * from tab/dba_tables/dba_objects/cat; 看用户建立的表 :  select table_name from user_tables;  //当前用户的表 select table_name from all_tables;  //所有用户的表 select table_name from dba_tables;  //包

0评论2023-02-10857

Oracle sql 子字符串长度判断
Oracle sql 子字符串长度判断 select t.* from d_table t WHEREsubstr(t.col,1,1)='8' and instr(t.col,'/')0 and length(substr(t.col,1,instr(t.col,'/')))5; 字符串的前两位都是数字:select * from d_table t WHERE regexp_like(substr(t.col,1,2), '^[

0评论2023-02-10759

Oracle、MySql、Sql Server比对
MySql:廉价(部分免费):当前,MySQL採用双重授权(DualLicensed),他们是GPL和MySQLAB制定的商业许可协议。假设你在一个遵循GPL的***(开源)项目中使用MySQL,那么你能够遵循GPL协议免费使用MySQL。否则,你须要购买MySQLAB制定的那个商业许可协议。Windows $

0评论2023-02-10441

Oracle 存储过程,临时表,动态SQL测试
--创建事务级别的结果临时表create global temporary table tmp_yshy( c1 varchar2(100), c2 varchar2(100))on commit delete rows;--创建事务级别的存储sql语句的临时表create global temporary table tmp_sql( c1 varchar2(4000))on commit delete rows;测

0评论2023-02-10508

Oracle PL/SQL开发利器-Toad应用总结(一)-PL/SQL Program基本编写、调试
转:http://ckitpro8086.blog.51cto.com/3653012/770589使用Toad进行Oracle PL/SQL Program的编写及调试需掌握如下视图应用:(1)Schema Broswer    模式浏览器(Schema Browser)可以快速访问数据字典,浏览数据库中的表、索引、存储过程。Toad 提供对数

0评论2023-02-10421

MySQL与Oracle的区别之我见 mysql oracle 区别
1. 大的方面(宏观)Oracle为商用数据库,行业中占据相当的地位:市场占比2012年为40%。开发、管理资源相当丰富,有自己的metalink,我也曾用过,有什么问题,都能在那里得到较快速度的解决。开发用了近10年,虽然有些功能用起来挺鸡肋的(像分页),但它在OL

0评论2023-02-10801

sql: sybase 和 oracle 比较
1. sybase 和 oracle 比较 http://blog.itpub.net/14067/viewspace-1030014/Oracle采用多线索多进程体系结构Sybase采用单进程多线索体系结构Oracle和Sybase都采用多线索。采用多线索的模式,能用较少的线索管理大量的用户进程;并且,线索进程是动态可调整的

0评论2023-02-10504

如何在PL/SQL中修改ORACLE的字段顺序 oracle 数据库修改表字段顺序
今 天下午工作中遇到的问题,我需要将A表中的数据放到它的备份表A_1中去,但A_1表中缺少两个字段,于是我就给它加上两个字段,但新加的字段会默认排在 在最后面,与表A中的字段顺序不一致,那么用insert into A_1 select * from A; 时就会出错。      

0评论2023-02-10493

公司Oracle生产库某用户中毒【AfterConnect.sql】
一、数据库中毒后症状1、无法通过客户端远程登录数据库。2、数据库会话连接被大量占用,进程数或会话数耗尽。3、所有的会话连接来自于数据库用户内部——非外部应用或者客户端占用。4、扩大会话数或者进程数,重启数据库服务后,会话连接数迅速占满。5、数据

0评论2023-02-10948

Qt数据库操作(qt-win-commercial-src-4.3.1,VC6,Oracle,SQL Server)
qt-win-commercial-src-4.3.1、qt-x11-commercial-src-4.3.1Microsoft Visual C++ 6.0、KDevelop 3.5.0Windows Xp、Solaris 10、Fedora 8SQL Server、Oracle 10g Client ■、驱动编译这里要提及两个数据库驱动,分别是ODBC和OCIWindows操作系统中编译ODBC驱

0评论2023-02-10398

Oracle,查询表的创建时间和最后修改时间sql
SELECT * FROM USER_TABLES 查看当前用户下的表SELECT * FROM DBA_TABLES 查看数据库中所有的表SELECTCREATED,LAST_DDL_TIME from user_objects where object_name=upper('表名')SELECT CREATED, LAST_DDL_TIMEFROM USER_OBJECTSWHERE OBJECT_NAME = 'PDCA_NE

0评论2023-02-10393

oracle下拼同比环比查询sql方法
拼接方法:        /// summary/// 生成计算同比环比查询语句/// table:表名称;statColumns:要统计的值字段;yearColumn:年份字段名;monthColumn:月份字段名;joinColumns:除年月外的连接条件/// --上期无值或0本期有值不为0:1/// --上期有值不为0

0评论2023-02-10642

更多推荐