zoukankan      html  css  js  c++  java
  • SQL Cookbook—查询、排序

    涉及到的问题
    1、在select语句中使用条件逻辑
    2、限制返回的行数
    3、从表中随机返回n条记录
    4、将空值转换为实际值
    5、对字母和数字混合的数据排序
    6、处理排序空值
    7、根据数据项的键排序
    –8、从一个表中查找另一个表没有的值
    –9、在一个表中查找与其他表不匹配的记录
    –10、向查询中增加联接而不影响其他联接
    –11、检测两个表中是否有相同的数据
    –12、从多个表中返回丢失的数据
    –13、在运算和比较时使用null值

    –1、在select语句中使用条件逻辑
    select ename,
           sal,
           case when sal<=2000 then 'UNDERPAID'
                when sal>=4000 then 'OVERPAID'
         else 'OK'
           end as status
    from emp
          

    –2、限制返回的行数
    select * from emp where rownum<=5

    –3、从表中随机返回n条记录
    select * from (
           select ename, job from emp order by dbms_random.value()
    )
    where rownum <= 5

    –4、将空值转换为实际值
    –方法一
    select comm, nvl(comm, 0) comm from emp
    –方法二
    select comm, coalesce(comm, 0) from emp
    –方法三
    select comm,
           case when comm is null then 0
           else comm
           end comm
    from emp

    –5、对字母和数字混合的数据排序
    –问题:现有字母和数字混合的数据,希望按照数字或字母部分来排序。考虑这个视图:
    create view v_tt as
    select ename||' '||deptno data from emp;

    主要是通过replace和translate来实现
    //by deptno(对数字排序)  
    select * from v_tt order by replace(data, replace(translate(data, '0123456789', '##########'), '#', ''), '');
    //by ename(对字母排序)
    select * from v_tt order by replace(translate(data, '0123456789', '##########'), '#', ''); 

    补充:translate函数用法
    select translate('123abc','2dc','4e') from dual;
    因为from_string和to_string的位置是一一对应的,2对应4,d对应e,c没有对应的值,所以c应该会被删除。所以例子的字符里的2会替换为4,d因为字符串里没有,所以不作替换,c由于没有对应的替换字符,所以字符串里的c会被删除,那么可以得出,结果是143ab

    –6、处理排序空值
    主要方法是通过使用CASE表达式来“标记”一个值是否为NULL。这里标记有两个值,一个表示NULL,一个表示非NULL。这样,只要在ORDER BY子句中增加标记列,便可以很容易的控制空值是排在前面还是排在后面,而不会被空值所干扰。

    //非空值按升序排序,空值排最后
    select ename,sal,comm from(
       select ename,sal,comm,
       case when comm is null then 0 else 1 end as is_null
       from emp
    ) x order by is_null desc,comm

    //非空值按降序排序,空值排最后
    select ename,sal,comm from(
       select ename,sal,comm,
       case when comm is null then 0 else 1 end as is_null
       from emp
    ) x order by is_null desc,comm desc

    //非空值按升序排序,空值排最前面
    select ename,sal,comm from(
        select ename,sal,comm,
        case when comm is null then 0 else 1 end as is_null
        from emp
    ) x order by is_null,comm

    //非空值按降序排序,空值排最前面
    select ename,sal,comm from(
       select ename,sal,comm,
       case when comm is null then 0 else 1 end as is_null
       from emp
    ) x order by is_null,comm desc


    在ORACLE中还可以使用NULLS FIRST和NULLS LAST来实现如上功能
    //非空值按升序排序,空值排最后
    select ename,sal,comm
    from emp
    order by comm nulls last
    //非空值按降序排序,空值排最后
    select ename,sal,comm
    from emp
    order by comm desc nulls last
    //非空值按升序排序,空值排最前面
    select ename,sal,comm
    from emp
    order by comm nulls first
    //非空值按降序排序,空值排最前面
    select ename,sal,comm
    from emp
    order by comm desc nulls first

    –7、根据数据项的键排序
    要根据某些条件逻辑来排序。例如,如果JOB是SALESMAN,要根据COMM来排序。否则,根据SAL排序。
    select ename,sal,job,comm from emp
    order by case when job ='SALSEMAN' then comm else sal end


    –8、从一个表中查找另一个表没有的值
    问题:从表dept中查找在表emp中不存在的数据的所有部门。示例数据中deptno的值在emp中不存在。
    方法一:
    select deptno from dept
    minus
    select deptno from emp
    方法二:
    select deptno from dept where deptno not in (select deptno from emp where deptno is not null)

    注意:
    1)、oracle中not in如果返回的有null值的话,不会返回记录。
    例如:select deptno from dept where deptno not in (10, 20, null)
    2)、在sql中,true or null的结果是true,而false or null的结果是null,所以在使用in和or计算时,值可能是null的情况,这一点要记住。

    要解决not in这样问题,可以使用not exists和相关子查询(推荐)
    select deptno from dept d where not exists(select 'xx' from emp e where e.deptno = d.deptno)

    –9、在一个表中查找与其他表不匹配的记录
    问题:对于具有相同关键字的两个表,要在一个表中查找与另一个表中不匹配的行。例如,要查找没有职员的部门(emp为从表)。
    select d.* from emp e, dept d where e.deptno(+)=d.deptno and e.deptno is null

    –10、向查询中增加联接而不影响其他联接
    例如,要获得所有的员工信息、他们的工作部门的地点以及所获得的奖励
    select e.ename, d.loc, eb.received
    from emp e, dept d, emp_bonus eb
    where e.deptno = d.deptno and e.empno = eb.empno

    这样的查询结果,如果员工没有奖金,则无法显示该员工的信息,那么,无论有无奖金都要显示员工信息,就要使用到外连接
    select e.ename, d.loc, eb.received
    from emp e, dept d, emp_bonus eb
    where e.deptno = d.deptno and e.empno = eb.empno(+)
    order by 2

    –11、检测两个表中是否有相同的数据
    create view v2
    as select * from scott.emp where deptno!=10
    union all
    select * from scott.emp where ename=upper('ward')   

    原理:
    1)、首先,查找出表emp中存在而视图v2中没有的行。
    2)、然后,合并在视图v2中存在,而在表emp中没有的行。
    (select empno,ename,job,mgr,hiredate,sal,comm,deptno,count(*) as cnt
     from v2
     group by empno,ename,job,mgr,hiredate,sal,comm,deptno
     minus
     select empno,ename,job,mgr,hiredate,sal,comm,deptno,count(*) as cnt
     from scott.emp
     group by empno,ename,job,mgr,hiredate,sal,comm,deptno)
     union all
    (select empno,ename,job,mgr,hiredate,sal,comm,deptno,count(*) as cnt
     from scott.emp
     group by empno,ename,job,mgr,hiredate,sal,comm,deptno
     minus
     select empno,ename,job,mgr,hiredate,sal,comm,deptno,count(*) as cnt
     from v2
     group by empno,ename,job,mgr,hiredate,sal,comm,deptno)

    –12、从多个表中返回丢失的数据
    select d.deptno,d.dname,e.ename from scott.dept d,scott.emp e
    where d.deptno=e.deptno(+)
    union
    select d.deptno,d.dname,e.ename from scott.dept d,scott.emp e
    where d.deptno(+)=e.deptno

    –13、在运算和比较时使用null值
    select ename, comm from scott.emp where coalesce(comm,0) < (select comm from scott.emp where ename=upper('ward'));       

  • 相关阅读:
    DB2 db2move导入导出数据及使用dblook导出表结构DDL
    【转】DB2 BLOB大字段数据通过命令行进行导入导出
    【转】【DataGuard】Oracle 11g物理Data Guard之Snapshot Standby数据库功能
    【转】Oracle 11g R2手动配置EM
    【转】Oracle Database Server 'TNS Listener'远程数据投毒漏洞(CVE-2012-1675)
    【转】ORACLE TNS Listener远程注册投毒(Poison Attack)漏洞
    【转】Oracle 11.2.0.4/12C新特性Valid Node Checking For Registration (VNCR)
    【转】使用 xtrabackup 进行MySQL数据库物理备份
    【转】MySQL-物理备份-Percona XtraBackup 备份原理
    【转】NBU expired Media,Media ID not found in EMM database
  • 原文地址:https://www.cnblogs.com/linjiqin/p/3152588.html
Copyright © 2011-2022 走看看