当前所在位置:珠峰网资料 >> 计算机 >> Oracle认证 >> 正文
Oracle通用函数 分组函数 子查询
发布时间:2010/8/20 10:50:00 来源:城市学习网 编辑:ziteng
  注意:1)Oracle中的字符串是严格区分大小写的,日期和字符只能在单引号中出现;
  2)把列与列,列与字符连接在一起用 ‘||’符号;
  3)列的别名,紧跟列名,也可以在列名和别名之间加入关键字‘AS’,以便在别名中包含空格或特殊的字符并区分大小写,使用双引号。
  例子:
  SELECT    last_name  ||  ' is a '  ||  job_id   AS  "Employee Details"
  FROM    employees
  where    first_name  like  '%s_';
  通用函数
  空值是无效的,未指定的,未知的或不可预知的值,空值不是空格或者0 ,包含空值的数学表达式的值都为空值。
  这些函数适用于任何数据类型,同时也适用于空值:
  NVL (expr1, expr2)
  NVL2 (expr1, expr2, expr3)
  NULLIF (expr1, expr2)
  COALESCE (expr1, expr2, ..., exprn)
  (1)NVL (expr1, expr2) ->expr1为NULL,返回expr2;不为NULL,返回expr1。注意两者的类型要一致
  (2)NVL2 (expr1, expr2, expr3) ->expr1不为NULL,返回expr2;为NULL,返回expr3。expr2和expr3类型不同的话,expr3会转换为expr2的类型
  (3)NULLIF (expr1, expr2) ->相等返回NULL,不等返回expr1
  (4)COALESCE(expr1, expr2, ..., exprn) ->列表中第一个非空的表达式是函数的返回值,如果所有的表达式都是空值,最终将返回一个空值。
  条件表达式在SQL语句中使用IF-THEN-ELSE 逻辑。可以使用两种方法:–CASE表达式    CASE  expr  WHEN  comparison_expr1  THEN  return_expr1                    [WHEN  comparison_expr2  THEN  return_expr2                     WHEN  comparison_exprn  THEN  return_exprn                     ELSE  else_expr]    END
  –DECODE函数    DECODE ( col | expression,  search1,  result1                [, search2, result2,...,]                [, default] )
  分组函数
  分组函数作用于一组数据,并对一组数据返回一个值。
  组函数语法:
  SELECT [column,] group_function(column), ...
  FROM table
  [WHERE condition]
  [GROUP BY column]
  [ORDER BY column];
  注意:在SELECT列表中所有未包含在组函数中的列都应该包含在GROUP BY子句中;
  (所用包含于SELECT列表中,而未包含于组函数中的列都必须包含于GROUPBY子句中)
  但包含在GROUP BY 子句中的列不必包含在SELECT列表中;
  且可以在在GROUP BY子句中包含多个列;
  不能在WHERE子句中使用组函数;但可以在HAVING子句中使用组函数。
  使用HAVING过滤分组:
  1.行已经被分组;
  2.使用了组函数;
  3.满足HAVING子句中条件的分组将被显示;
  SELECT column, group_function
  FROM table
  [WHERE condition]
  [GROUP BY group_by_expression]
  [HAVING group_condition]
  [ORDER BY column]; [NextPage]  子查询
  语法:
  SELECT select_list
  FROM table
  WHERE expr operator
  (SELECT select_list
  FROM table);
  注意:子查询(内查询) 在主查询之前一次执行完成;
  子查询的结果被主查询使用(外查询);
  子查询要包含在括号内;
  将子查询放在比较条件的右侧;
  除非进行Top-N 分析,否则不要在子查询中使用ORDER BY子句;
  单行操作符对应单行子查询,多行操作符对应多行子查询。
  单行操作符operator:                                                    多行操作符operator :
  =    等于                                                                            IN     等于列表中的任何一个
  >    大于                                                                            ANY  和子查询返回的任意一个值比较
  >=  大于等于                                                                    ALL   和子查询返回的所有值比较
  <    小于                                                                            EXISTS  功能等价于IN
  <=  小于等于
  <>  不等于
  DECODE和CASE,SELECT中除GROUP BY 子句以外的所有子句中,都可以使用单行子查询。
  在子查询中使用HAVING子句:
  SELECT select_list
  FROM table
  [GROUP BY group_by_expression]
  [HAVING group_condition] expr operator
  (SELECT select_list
  FROM table);
  在FROM子句中使用子查询,例子:
  SELECT a.last_name, a.salary, a.department_id, b.salavg
  FROM employees a, (SELECT department_id, AVG(salary) salavg
  FROM employees
  GROUP BY department_id) b
  WHERE a.department_id = b.department_id
  AND   a.salary > b.salavg;
  有两个简单例子,以说明 “exists”和“in”的效率问题
  1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ;
  T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高。
  2) select * from T1 where T1.a in (select T2.a from T2) ;
  T1数据量非常大而T2数据量小时,T1>>T2 时,2) 的查询效率高。
  exists 用法:
  请注意 1)句中的有颜色字体的部分 ,理解其含义;
  其中 “select 1 from T2 where T1.a=T2.a” 相当于一个关联表查询,相当于
  “select 1 from T1,T2     where T1.a=T2.a”
  但是,如果你当当执行 1) 句括号里的语句,是会报语法错误的,这也是使用exists需要注意的地方。
  “exists(xxx)”就表示括号里的语句能不能查出记录,它要查的记录是否存在。
  因此“select 1”这里的 “1”其实是无关紧要的,换成“*”也没问题,它只在乎括号里的数据能不能查找出来,是否存在这样的记录,如果存在,这 1) 句的where 条件成立。  in 的用法:
  继续引用上面的例子
  “2) select * from T1 where T1.a in (select T2.a from T2) ”
  这里的“in”后面括号里的语句搜索出来的字段的内容一定要相对应,一般来说,T1和T2这两个表的a字段表达的意义应该是一样的,否则这样查没什么意义。
  打个比方:T1,T2表都有一个字段,表示工单号,但是T1表示工单号的字段名叫“ticketid”,T2则为“id”,但是其表达的意义是一样的,而且数据格式也是一样的。这时,用 2)的写法就可以这样:
  “select * from T1 where T1.ticketid in (select T2.id from T2) ”
  EXISTS操作符
  EXISTS 操作符检查在子查询中是否存在满足条件的行
  - 如果在子查询中存在满足条件的行:
  – 不在子查询中继续查找
  – 条件返回TRUE
  - 如果在子查询中不存在满足条件的行:
  – 条件返回FALSE
  – 继续在子查询中查找
  相关子查询
  相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。子查询使用了主查询中的列。
  SELECT  column1, column2, ...
  FROM  table1 outer
  WHERE columnk operator (SELECT  colum1, colum2
  FROM  table2
  WHERE expr= outer.expr);
  相关更新
  使用相关子查询依据一个表中的数据更新另一个表的数据。
  UPDATE  table1 alias1
  SET  column = (SELECT  expression
  FROM  table2  alias2
  WHERE  alias1.column = alias2.column);
  相关删除
  使用相关子查询依据一个表中的数据删除另一个表的数据。
  DELETE FROM  table1 alias1
  WHERE  column operator (SELECT  expression
  FROM  table2 alias2
  WHERE alias1.column = alias2.column);
  WITH子句
  - 使用WITH子句,可以避免在SELECT语句中重复书写相同的语句块
  - WITH子句将该子句中的语句块执行一次,并存储到用户的临时表空间中
  - 使用WITH子句可以提高查询效率
  我们可以使用WITH  Clause来定义一个query   block,然后在SELECT   statement的其它地方使用这个query   block。如果在一个很复杂的 Query 里,我们必须重复地使用某个 subquery,那么使用WITH   Clause可以降低Query的复杂度以及提高 performance。因为WITH   Clause 所读出的资料会暂存在User的temporary   tablespace中。
  WITH子句应用举例:
  WITH
  dept_costs AS (SELECT  d.department_name, SUM(e.salary) AS dept_total
  FROM  employees e, departments d
  WHERE  e.department_id = d.department_id
  GROUP BY  d.department_name),
  avg_cost  AS (SELECT  SUM(dept_total)/COUNT(*) AS dept_avg
  FROM  dept_costs)
  [NextPage]   SELECT  *
  FROM  dept_costs
  WHERE  dept_total > (SELECT  dept_avg
  FROM  avg_cost)
  ORDER BY  department_name;
  GROUP BY 扩展
  带有ROLLUP和CUBE操作的GROUP BY子句
  - 使用带有ROLLUP和CUBE操作的GROUP BY子句产生多种分组结果
  - ROLLUP产生n + 1种分组结果,其是对GROUP BY子句的扩展
  - CUBE产生2的n次方种分组结果,其是对GROUP BY子句的扩展
  注:其中的n指的是group_by_expression的数目。
  ROLLUP操作符 :ROLLUP产生n + 1种分组结果,顺序是从右向左
  SELECT  [column,] group_function(column). . .
  FROM  table
  [WHERE condition]
  [GROUP BY [ROLLUP] group_by_expression]
  [HAVING having_expression]
  [ORDER BY column];
  CUBE操作符:CUBE会产生类似于笛卡尔集的分组结果
  SELECT  [column,] group_function(column). . .
  FROM  table
  [WHERE condition]
  [GROUP BY [CUBE] group_by_expression]
  [HAVING having_expression]
  [ORDER BY column];
  GROUPING函数:能够实现更加直观的分组结果显示提示
  SELECT  [column,] group_function(column) . , [GROUPING(group_by_expression)]..
  FROM  table
  [WHERE condition]
  [GROUP BY  [ROLLUP] [CUBE] group_by_expression]
  [HAVING having_expression]
  [ORDER BY column];
  - GROUPING函数可以和CUBE或ROLLUP结合使用
  - 使用GROUPING函数,可以找到哪些列在该行中参加了分组
  - 使用GROUPING函数, 可以区分空值产生的原因
  - GROUPING函数返回0 或1
  GROUPING SETS:
  - GROUPING SETS是对GROUP BY子句的进一步扩充
  - 使用GROUPING SETS可以实现在同一个查询中定义多个分组集
  - Oracle 对GROUPING SETS子句指定的分组集进行分组后用UNION ALL操作将各分组结果结合起来
  - Grouping set 的优点:
  – 只进行一次分组即可
  – 不必书写复杂的UNION语句
  – GROUPING SETS中包含的分组项越多性能越好
  以下例子实现了对department_id, job_id分组,对job_id, manager_id分组,最终形成两个分组:
  SELECT  department_id, job_id, manager_id, avg(salary)
  FROM  employees
  GROUP BY GROUPING SETS ((department_id, job_id), (job_id, manager_id));
  复合列
  - 复合列是被作为整体处理的一组列的集合
  - 使用括号将若干列组成复合列在ROLLUP或CUBE中作为整体进行操作
  - 在ROLLUP或CUBE中,复合列可以避免产生不必要的分组结果
  例如:GROUP BY ROLLUP( department_id, (job_id, manager_id)); //小括号实现复合列
  连接分组集
  - 连接分组集可以产生有用的对分组项的结合
  - 将各分组集、ROLLUP 和CUBE用逗号连接,Oracle自动在GROUP BY子句中将各分组集进行连接
  - 连接的结果是对各分组生成笛卡尔集
  例如:GROUP BY GROUPING SETS(a, b), GROUPING SETS(c, d);
  例如:GROUP BY department_id, ROLLUP(job_id), CUBE(manager_id);
广告合作:400-664-0084 全国热线:400-664-0084
Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号
珠峰网 版权所有 All Rights Reserved