一个查询语句各个部分的执行顺序: 

--8)  SELECT (9) DISTINCT (11) <TOP_specification> <select_list> 
--(1)  FROM <left_table> 
--(3)    <join_type> JOIN <right_table> 
--(2)      ON <join_condition> 
--(4)  WHERE <where_condition> 
--(5)  GROUP BY <group_by_list> 
--(6)  WITH {CUBE | ROLLUP} 
--(7)  HAVING <having_condition> 
--(10) ORDER BY <order_by_list>

=============distinct===========

  1. distinct 一般是放在select之后;

  2. 如果是所有查询出来的都要distinct,直接在select后加distinct 关键词就可以;

  3. 如果是单列,可以用distinct(col)函数

    demo:

    id name

    1 a
    2 b
    3 c
    4 c
    5 b

    查询不同name,但同时需要id列:

select *, count(distinct name) from table group by name

================

SQL Select语句完整的执行顺序:
1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、使用order by对结果集进行排序。 

执行顺序:
                  
1. FROM 子句返回初始结果集。
                  
2. WHERE 子句排除不满足搜索条件的行。
                  
3. GROUP BY 子句将选定的行收集到 GROUP BY 子句中各个唯一值的组中。
                  
4. 选择列表中指定的聚合函数可以计算各组的汇总值。
                  
5. 此外,HAVING 子句排除不满足搜索条件的行。
                  
6. 计算所有的表达式;
                  
7. 使用order by对结果集进行排序。
                  
8.查找你要搜索的字段。
用SELECT命令表达查询的较完整的语法格式是:
        
SELECT<目标表的列名或列表达式序列>
        
FROM<表名序列>
        
[WHERE<行条件表达式>]
        
[GROUP BY<列名>
        
[HAVING<组条件表达式>]]
        
[ORDER BY<列名>[DESC],…];
其执行过程如下:
    
(1) 读取FROM子句中表或视图的数据,执行笛卡尔乘积操作。
    
(2) 选取满足WHERE子句中给出的条件表达式的元组。
    
(3) 按GROUP子句中指定列的值分组,同时提取满足HAVING子句中组条件表达式的那些组。
    
(4) 按SELECT 子句中给出 的列名或列表达式求值输出。
    
(5) 按ORDER子句对输出的目标表进行排序,按附加说明DESC降序排列,默认为升序排列。
       
2.5   交叉(无限制)   连接
交叉连接用于对两个源表进行纯关系代数的乘运算。它不使用连接条件来限制结果集合,而是将分别来自两个数据源中的行以 所有可能的方式进行组合。数据集合中一的每个行都要与数据集合二中的每一个行分别组成一个新的行。例如,如果第一个数据源中有5个行,而第二个数据源中有 4个行,那么在它们之间进行交叉连接就会产生20个行。人们将这种类型的结果集称为笛卡尔乘积。
大多数交叉连接都是由于错误操作而造成的;但是 它们却非常适合向数据库中填充例子数据,或者预先创建一些空行以便为程序执行期间所要填充的数据保留空间。
select   *
from     t_institution   i
cross   join   t_teller   t

在交叉连接中没有on条件子句

=========================

一旦sql语句中使用了group by子句后所有的聚合函数都变成对每一组起作用

使用group by的目的就是“细化聚合函数的作用对象”,若没有分组,则聚合函数作用于整个查询结果(所有行),一旦分了组,聚合函数则作用于“每一个组”,即每一个组都计算一次,每一组都有一个函数值。(聚合函数的执行在分组操作之后。)

select后面的列明必须是“分组列”或者“列函数”。

group by 与having:

having用在group by之后,对group by产生的分组进行按条件筛选,而having子句可以包含一个或者多个用and或or连接的谓词。

一般group by分组后,进行聚合函数的运算,接着会执行having,对结果进行筛选。

一条SQL语句个子句的先后作用过程:

from→where→group by→select(含聚合函数)→order by

oracle中数据处理常用的sql语句与函数

SQL语句:

insert into ... select 

update ... set .....  select 

函数:

nvl 、 instr、 substr 、upper、trim、to_date、 length 

条件判断的函数:

  (1)、 case when  表达式 1 成立  then 值1 when 表达式2 成立 值2   end  

  (2)、 decode[条件,值1,翻译值1,值2,翻译值2,.....值n,翻译值n,缺省值]

       (翻译:if 条件=值1 return (翻译值1))

1、更改oracle默认的时间格式:

 alter session set  NLS_DATE_FORMAT = 'yyyy-mm-dd'

上面的修改只是临时的,数据库重启时会恢复默认的日期,若要修改注册表过滤器分组

2、保存点的使用

   savepoint a ; --创建保存点

    delete from dd ;

    rollback to a ; --回滚到保存点a状态

3、oracle中AS别名的使用注意事项:

    1)、select ename 姓名, sal from scott.emp (正确),不使用引号

    2)、select ename  '姓名', sal from scott.emp (错),单引号

    3)、select ename  “姓名”, sal from scott.emp (正确),双引号

4、规定:

    多表查询的条件是:至少不能少于(表的个数 - 1)个条件,这样才能排除笛卡尔积。(一般,N张表联合,则必须得 N-1个条件,才可以避免笛卡尔积。)

5、自连接;

select ... from emp worker , emp boss where .....

6、当在from子句中使用子查询时,该子查询会被当作一个视图来对待,因此叫做内嵌视图,当在from子句中使用子查询时,必须给子查询指定别名(别名不能用as)。根据

7、oracle分页形式

 1)、根据rowid分页

2)、分析函数                           3)、rownum

8、 union:取得两个结果的并集,使用该操作时会自动去掉结果集中重复行。(union all 不   会去除重复行)。

  intersect : 使用该操作符用于取得两个结果的交集。

10、插入数据时,使用了values后一次只能插入一行数据。

11、group by 有一个原则:就是select后面的所有列中,没有使用聚合函数的列,必须出现在group by后面。

 e.g. 

 select ename , max(sal) from emp ------(error) 非单组分组函数 (ename不是分组函数)

======================================================

insert into select 

insert into tab(filed1,field2,......) select v1 ,v2 , ...... from tab2

select into from 

    select  val1 , val2 ,val3  into tab1 from  tab2 

select  instr('abcde' , 'ab') from dual 

查找并删除同一个表中的重复记录(利用rowid)
                                                                                                                                                       
a 表(bm , mc)
select 
rowid, bm,mc 
from 
where 
a.rowid !=
  
(selct 
max
(rowid) 
from 
a b 
where 
a.bm = b.bm 
and 
a.mc = b.mc)
                                                                                                                                                       
删除: 
delete 
from 
where 
a.rowid != (
select 
max
(rowid) 
from 
a b 
where 
a.bm = b.bm 
and 
a.mc= b.mc)
或者
delete 
from 
where 
where 
rowid 
not 
in
select 
max
(rowid) 
from 
group 
by 
bm ,mc)
                                                                                                                                                       
insert 
into 
select 
a,b,c,[子查询] ...(该
select
语句中必须包含A中的所有字段

删除重复记录:最高效的删除重复记录方法 ( 因为使用了ROWID)例子:

DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO);

Update

1、将一个表中的字段更新到另一个表中的字段;

  update A set a.field1 = (select  b.field1 from b where a.field2 = b.field2)

where exists(select 1 from b where a.field2 = b.field2)

2、Update语句原理: 先根据where条件筛选符合条件的记录,然后进行更新(查询--》更新

 update语句先根据where条件查询到数据后,如果set中有子查询,则执行子查询把值查出来给更新的字段,执行更新。

(关联表更新时一定要有 类似exists(select 1 from b where a.field2 = b.field2)的条件否则经表a的其他数据个字段1更新为null值)

查表a的所有数据,循环每条数据,验证该条数据是否符合exists(select 1 from 表b where a.字段2=b.字段2)条件,如果是则执行(select b.字段1 from 表b where a.字段2=b.字段2)查询,查到对应的值更新a.字段1中。关联表更新时一定要有exists(select 1 from 表b where a.字段2=b.字段2)这样的条件,否则将表a的其他数据的字段1更新为null值。

update set(A1,A2,A3) = (select B1,B2,B3) from where A.id = B.id)

===========================

inline view更新法 

inline view更新法就是更新一个临时建立的视图。如:

update (select a.join_state as join_state_a,b.join_state as join_state_b from 

t_join_situation a, t_people_info b where a.people_number=b.people_number  

and a.year='2011' and a.city_number='M00000' and 

a.town_number='M51000') 

set join_state_a=join_state_b 

括号里通过关联两表建立一个视图,set中设置好更新的字段。

这个解决方法比写法较直观且执行速度快。但表B的主键一定要在where条件中,

并且是以“=”来关联被更新表。

快速游标更新法 

语法如: 

begin

 for cr in (查询语句) loop –-循环  

--更新语句(根据查询出来的结果集合) 

end loop; --结束循环 

end; 

oracle支持快速游标,不需要定义直接把游标写到for循环中,

这样就方便了我们批量更新数据。再加上oracle的rowid物理字段(

oracle默认给每个表都有rowid这个字段,并且是唯一索引),

可以快速定位到要更新的记录上。例如:

beginfor cr in (select a.rowid,b.join_state from t_join_situation a,t_people_info b  where a.people_number=b.people_number and a.year='2011' and a.city_number='M00000' and a.town_number='M51000') loopupdate t_join_situation set join_state=cr.join_state whererowid = cr.rowid; end loop; end;