With temp as---sql语句用法 转

文章出处:http://blog.163.com/[email protected]/blog/static/49479943201171710305298/  感谢作者的分享

3.1 with基础

  

  使用WITH AS 语句可以为一个子查询语句块定义一个名称,使用这个子查询名称可以在查询语句的很多地方引用这个子查询。Oracle 数据库像对待内联视图或临时表一样对待被引用的子查询名称,从而起到一定的优化作用。with子句是9i新增语法。

  你可以在任何一个顶层的SELECT 语句以及几乎所有类型的子查询语句前,使用子查询定义子句。被定义的子查询名称可以在主查询语句以及所有的子查询语句中引用,但未定义前不能引用。

  with子句中不能嵌套定义<也就是with子句中不能有with子句>,但子查询中出现的子查询定义语句可以引用已定义的子查询名称。<可以引用前面已经定义的with子句>

  with子句相关总结:

  

  1.使用with子句可以让子查询重用相同的with查询块,通过select调用(with子句只能被select查询块引用),一般在with查询用到多次情况下。在引用的select语句之前定义,同级只能定义with关键字只能使用一次,多个用逗号分割。

  2.with子句的返回结果存到用户的临时表空间中,只做一次查询,反复使用,提高效率。

  3.在同级select前有多个查询定义的时候,第1个用with,后面的不用with,并且用逗号隔开。

  5.最后一个with 子句与下面的查询之间不能有逗号,只通过右括号分割,with 子句的查询必须用括号括起来

  6.如果定义了with子句,而在查询中不使用,那么会报ora-32035 错误:未引用在with子句中定义的查询名。(至少一个with查询的name未被引用,解决方法是移除未被引用的with查询),注意:只要后面有引用 的就可以,不一定非要在主查询中引用,比如后面的with查询也引用了,也是可以的。

  7.前面的with子句定义的查询在后面的with子句中可以使用。但是一个with子句内部不能嵌套with子句。

  8.当一个查询块名字和一个表名或其他的对象相同时,解析器从内向外搜索,优先使用子查询块名字。

  9.with查询的结果列有别名,引用的时候必须使用别名或*。

  with子句优点:

  

  1. SQL可读性增强。比如对于特定with子查询取个有意义的名字等。

  2. with子查询只执行一次,将结果存储在用户临时表空间中,可以引用多次,增强性能。

  with子句语法:

  With alias_name as (select1), --as和select中的括号都不能省略

  alias_name2 as (select2),--后面的没有with,逗号分割,同一个主查询同级别地方,with子查询只能定义一次

  …

  alias_namen as (select n) –与下面的实际查询之间没有逗号

  Select ….

  with使用例子:

  1.一般使用方式

  

  如查询销售部门员工的姓名:

  --with clause

  with a as

  (select id from s_dept where name=Sales order by id)

  select last_name,title

  from s_emp where dept_id in (select * from a);--使用select查询别名

  使用with 子句,可以在复杂的查询中预先定义好一个结果集,然后在查询中反复使用,不使用会报错。而且with 子句获得的是一个临时表,如果在查询中使用,必须采用select from with 查询名,比如

  With cnt as(select count(*) from table)

  Select cnt+1 from dual;

  是错误的。必须是

  With cnt as(select count(*) shumu from user_tables)

  Select shumu+1 from cnt;

  2.在大多数子查询中引用,同级可见

  

  再如下面两个语句含义等价:

  with a as (select trade_id,name from product) --使用之前定义

  select name from a where a.trade_id in (

  with b as (select id from trademark where id=1) --使用之前定义

  select id from b

  );

  select name from product where trade_id in (select id from trademark where id=1);

  3. with子查询不可嵌套定义,但是后面的with定义可以引用前面的结果集。

  

  with select_trade as (select trade_id from product where id=1),

  --后面的with子查询可以引用前面的结果

  select_trademark as (select name from trademark where id=(select trade_id from select_trade))

  select * from select_trademark;

  --这条语句错误

  with select_trade as

  --with中有嵌套with,不允许

  ( with temp as ( select trade_id from product where id=1)

  select trade_id from temp

  ),

  select_trademark as (select name from trademark where id=(select trade_id from select_trade))

  select * from select_trademark;

  4. 同级定义,只能有一个with

  

  with a as (select trade_id from product),

  b as (select id from trademark where rownum<3) --第2个定义不用with

  select trade_id from a

  minus

  select id from b;

5. 在大多数子查询中定义和使用,一个复杂的例子

  

  SELECT a ,b

  FROM (

  --第1个定义t_with

  WITH

  t_with AS (SELECT 1 a FROM DUAL)

  --子查询使用t_with

  SELECT x.a ,(

  --内部定义了个t_with_z,并且使用t_with

  WITH t_with_z as (SELECT 1 a FROM t_with )

  SELECT s_1.a FROM t_with_z s_1 ,t_with s_2

  6. 集合中使用with子查询

  

  --这个是错误的,同级只能有一个with定义,当然两个可以写在一起。

  SELECT *

  FROM (

  WITH

  t_with_1 AS (SELECT 1 a ,1 b FROM DUAL)

  --此后的整个语句被认为是一个主查询语句

  SELECT x.a , x.b FROM t_with_1 x

  union all

  WITH -- 此处再次出现定义

  t_with_2 AS (SELECT 1 a ,2 b FROM DUAL)

  SELECT y.a ,y.b FROM t_with_2 y

  --正确

  SELECT *

  FROM (

  --第1个with

  WITH

  t_with_1 AS (SELECT 1 a ,1 b FROM DUAL)

  SELECT x.a , x.b ,x c FROM t_with_1 x

  union all

  --这里不能用with再次定义,同级只能有1个with,可以写在最前面

  --内部with

  SELECT y.a ,y.b , (WITH

  t_with_x AS (SELECT * FROM t_with_1)

  SELECT a FROM t_with_x )

  FROM ( WITH

  t_with_2 AS (SELECT 1 a ,2 b FROM DUAL)

  SELECT a ,b FROM t_with_2

  ) y

  WHERE y.a = (

  with t_with_3 AS (SELECT 1 a ,2 b FROM DUAL)

  select a from t_with_3

  )

  )

  7.一个with查询的实例:

  

  查询出部门的总薪水大于所有部门平均总薪水的部门。部门表s_dept,员工表s_emp。分析:做这个查询,首先必须计算出所有部门的总薪 水,然后计算出总薪水的平均薪水,再筛选出部门的总薪水大于所有部门总薪水平均薪水的部门。那么第1 步with 查询查出所有部门的总薪水,第2 步用with 从第1 步获得的结果表中查询出平均薪水,最后利用这两次的with 查询比较总薪水大于平均薪水的结果,如下:

  with

  --step1:查询出部门名和部门的总薪水

  dept_costs as(

  select a.name,sum(b.salary) dept_total

  from

  s_dept a,s_emp b

  where a.id=b.dept_id

  group by a.name

  ),

  --step2:利用上一个with查询的结果,计算部门的平均总薪水

  avg_costs as(

  select sum(dept_total)/count(*) dept_avg

  from dept_costs

  )

  --step3:从两个with查询中比较并且输出查询结果

  select name,dept_total

  from dept_costs

  where

  dept_total>

  (

  select dept_avg

  from

  avg_costs

  )

  order by name;

  从上面的查询可以看出,前面的with 查询的结果可以被后面的with查询重用,并且对with 查询的结果列支持别名的使用,在最终查询中必须要引用所有with 查询,否则会报错ora-32035 错误。

  再如有这样一个需求:一个查询,如果查询的结果行不满足是10 的倍数,则补空行,直到是查询出的行数是10 的倍数。例如:select * from trademark这个查询。

3.2 11G R2with新特性

  

  新版本的WITH 允许递归使用,在功能上比原来有了质的飞跃,可以实现许多原来CONNECT BY做不到的事。

  3.3 with对执行计划的影响

  

  with子句有可能会改变执行计划。

时间: 2024-10-17 05:50:06

With temp as---sql语句用法 转的相关文章

MySQL 中delete删除sql语句用法

mysql如何要删除一个一行或者多行,用sql语句delete关键词,固定用法 delete from 表名. 1,delete删除一行 delete from student where id=1 2,delete删除多行 delete from student where in (1,2,3) 3,删除表的所有数据 delete from student 请使用不带where子句的delete语句 文章来自 http://www.dc3688.com 原文地址:http://blog.51c

python中的 sql语句用法

函数中应用sql语句def _get_cust_number(self,cr,uid,ids,field_name,args,context=None): res={} for order in self.browse(cr, uid, ids, context=context): #获取单据信息 aa=order.origin if aa: sql="select t1.cust_numr_no from stock_fah t0 left join sale_orde t1 on t0.or

自己不懂的SQL语句用法

left  join:是SQL语言中的查询类型,即连接查询.它的全称为左外连接,是外连接的一种. 连接通常可以在select语句的from子句或where子句中建立,其语法格式为: select  column_name1,column_name2 from table_name1 left join table_name2 on table_name1.columnname=table_name2.columnname 其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也

SQL 语句及关键字的用法

一.SELECT select [ALL|DISTINCT] select_list [into new table] FROM table_source [where serch_conditaion] [GROUP BY group_by_expression] [Having serch_conditaion] [Order by order_expression[ASC|DESC]] --从上面的语句可以看出SELECT 查询语句共有5个子句 其中SELECT\FROM 为必选语句 --

SQL 语句日期用法及函数

SQL 语句日期用法及函数 --DAY().MONTH().YEAR()——返回指定日期的天数.月数.年数:select day(cl_s_time) as '日' from class  --返回天select '月'=month(cl_s_time) from class  --返回月select '年'=year(cl_s_time) from class  --返回年 --DATEADD(datepart,number,date)——在日期上增加给定日期类型的数量:select date

SQL语句的用法

SQL语句的用法 SQL 简介 SELECT DISTINCT WHERE AND OR IN 函数 INCLUDE HAVING 简介 SQL语句教程 SELECT SELECT "列名" FROM "表格名"; 列名可以为多个,该选中的列显示出来 DISTINCT SELECT DISTINCT "列名" FROM "表格名"; 只显示不同的值,重复值不显示,如果有多个列,则每一个列的值都相同时视作相同.如下表,执行sel

SQL语句一些特殊的用法

一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份数据的 device USE master EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat' --- 开始 备份 BACKUP DATABASE pubs TO testBack 4.说明:创建

“取出数据表中第10条到第20条记录”的sql语句+select top 用法

1.首先,select top用法: 参考问题  select top n * from和select * from的区别 select * from table --  取所有数据,返回无序集合 select top n * from table  -- 根据表内数据存储顺序取前n条,返回无序集合 select * from table order by id desc -- 取所有数据,按id逆序返回有序列表 select top n * from table order by id des

SQL语句中having的用法

在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用. having子句用法一(来自w3school): SQL HAVING 语法如下 SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name HAVING aggregate_function(column_name) ope

SQL语句中count(1)count(*)count(字段)用法的区别

SQL语句中count(1)count(*)count(字段)用法的区别 在SQL语句中count函数是最常用的函数之一,count函数是用来统计表中记录数的一个函数, 一. count(1)和count(*)的区别 1. count(1)和count(*)的作用: 都是检索表中所有记录行的数目,不论其是否包含null值. 2. 区别:但是count(1)比count(*)效率更高 二 . count(字段)与count(1)和count(*)的区别 count(字段)的作用是检索表中的这个字段