Oracle通用函数,分组函数,子查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle通用函数,分组函数,子查询相关的知识,希望对你有一定的参考价值。

参考技术A

  注意 )Oracle中的字符串是严格区分大小写的 日期和字符只能在单引号中出现

   )把列与列 列与字符连接在一起用 || 符号

   )列的别名 紧跟列名 也可以在列名和别名之间加入关键字 AS 以便在别名中包含空格或特殊的字符并区分大小写 使用双引号

  例子

  SELECT    last_name  ||  is a   ||  job_id   AS  Employee Details

  FROM    employees

  where    first_name  like  %s_ ;

  通用函数

  空值是无效的 未指定的 未知的或不可预知的值 空值不是空格或者 包含空值的数学表达式的值都为空值

  这些函数适用于任何数据类型 同时也适用于空值

  NVL (expr expr )

  NVL (expr expr expr )

  NULLIF (expr expr )

  COALESCE (expr expr exprn)

  ( )NVL (expr expr ) >expr 为NULL 返回expr 不为NULL 返回expr 注意两者的类型要一致

  ( )NVL (expr expr expr ) >expr 不为NULL 返回expr 为NULL 返回expr expr 和expr 类型不同的话 expr 会转换为expr 的类型

  ( )NULLIF (expr expr ) >相等返回NULL 不等返回expr

  ( )COALESCE(expr expr exprn) >列表中第一个非空的表达式是函数的返回值 如果所有的表达式都是空值 最终将返回一个空值

  条件表达式在SQL语句中使用IF THEN ELSE 逻辑 可以使用两种方法:–CASE表达式    CASE  expr  WHEN  parison_expr   THEN  return_expr                     [WHEN  parison_expr   THEN  return_expr                      WHEN  parison_exprn  THEN  return_exprn                     ELSE  else_expr]    END

  –DECODE函数    DECODE ( col | expression   search   result                 [ search result ]                [ 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过滤分组

   行已经被分组

   使用了组函数

   满足HAVING子句中条件的分组将被显示

  SELECT column group_function

  FROM table

  [WHERE condition]

  [GROUP BY group_by_expression]

  [HAVING group_condition]

  [ORDER BY column];

  子查询

  语法

  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 的效率问题

   ) select * from T where exists(select from T where T a=T a) ;

  T 数据量小而T 数据量非常大时 T <<T 时 ) 的查询效率高

   ) select * from T where T a in (select T a from T ) ;

  T 数据量非常大而T 数据量小时 T >>T 时 ) 的查询效率高

  exists 用法

  请注意 )句中的有颜色字体的部分 理解其含义

  其中 select from T where T a=T a 相当于一个关联表查询 相当于

   select from T T      where T a=T a

  但是 如果你当当执行 ) 句括号里的语句 是会报语法错误的 这也是使用exists需要注意的地方

   exists(xxx) 就表示括号里的语句能不能查出记录 它要查的记录是否存在

  因此 select 这里的 其实是无关紧要的 换成 * 也没问题 它只在乎括号里的数据能不能查找出来 是否存在这样的记录 如果存在 这 ) 句的where 条件成立

  in 的用法

  继续引用上面的例子

   ) select * from T where T a in (select T a from T )

  这里的 in 后面括号里的语句搜索出来的字段的内容一定要相对应 一般来说 T 和T 这两个表的a字段表达的意义应该是一样的 否则这样查没什么意义

  打个比方 T T 表都有一个字段 表示工单号 但是T 表示工单号的字段名叫 ticketid T 则为 id 但是其表达的意义是一样的 而且数据格式也是一样的 这时 用 )的写法就可以这样

   select * from T where T ticketid in (select T id from T )

  EXISTS操作符

  EXISTS 操作符检查在子查询中是否存在满足条件的行

   如果在子查询中存在满足条件的行

  – 不在子查询中继续查找

  – 条件返回TRUE

   如果在子查询中不存在满足条件的行

  – 条件返回FALSE

  – 继续在子查询中查找

  相关子查询

  相关子查询按照一行接一行的顺序执行 主查询的每一行都执行一次子查询 子查询使用了主查询中的列

  SELECT  column column

  FROM  table outer

  WHERE columnk operator (SELECT  colum colum

  FROM  table

  WHERE expr= outer expr);

  相关更新

  使用相关子查询依据一个表中的数据更新另一个表的数据

  UPDATE  table alias

  SET  column = (SELECT  expression

  FROM  table   alias

  WHERE  lumn = lumn);

  相关删除

  使用相关子查询依据一个表中的数据删除另一个表的数据

  DELETE FROM  table alias

  WHERE  column operator (SELECT  expression

  FROM  table alias

  WHERE lumn = lumn);

  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)

  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 + 种分组结果 其是对GROUP BY子句的扩展

   CUBE产生 的n次方种分组结果 其是对GROUP BY子句的扩展

  注 其中的n指的是group_by_expression的数目

  ROLLUP操作符 ROLLUP产生n + 种分组结果 顺序是从右向左

  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函数返回 或

  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);

lishixinzhi/Article/program/Oracle/201311/18505

ORACLE分组排序查询

有一个表,A字段为唯一标示,B字段有重复数据,现在我想以B字段分组,以C字段显示每组的每条记录的子序号从“1”开始往后排。我这张表的数据很大,如果用row_number(),rank()这种函数可以实现,但是查询速度相当慢。哪位能提供一个快速的查询方法,句子多复杂都没事,只要求快。

row_number(),rank()是分析函数,是实现这种需求最高效的方法
你需要大表的排序,速度肯定不会快到哪里去
建议你对需要排序的字段先创建一个索引,会快很多很多
发放依然还是用row_number(),这个比较好
参考技术A 按照你说的功能部分估计只能是
select row_number() as A, B, rank() as C

from yourtable
group by B;
查询速度优化只能优先从数据过滤方面着手

以上是关于Oracle通用函数,分组函数,子查询的主要内容,如果未能解决你的问题,请参考以下文章

Oracle基本语法&&函数&&子查询&&分页查询&&排序&&集合操作&&高级分组函数

ORACLE分组排序查询

Mysql从入门到入魔——5. 聚集分组子查询

Oracle - 查询语句 - 分组函数

分组函数 多表连接 子查询

如何对具有聚合函数的 Oracle 查询进行分组