++++++++
SQL语句基础收集
++++++++
sql语句是一个DBA经常研究的问题,怎么执行高效,这个不是此处探讨的,这里只写其基本使用方法。作为DBA这些是必知必会的。
SQL语句总览:
DQL(数据查询语言):select
DML(数据操纵语言):insert,update,delete
DDL(数据定义语言): create,alter,drop(table|view|index)
DCL(数据控制语言): grant,revoke,rollback,commit(控制权限|事务)
逐个描述:
(一)select语句
语法:
select *|{[distinct]column|expression [alias],....} from table;
举例:
1.查看库名和实例名(在sys用户下使用)
SQL> select name from v$database;
NAME
---------
ORCL
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
orcl
2.算术表达式和空值
SQL> select ename,sal+10 from emp where deptno=10;
ENAME SAL+10
---------- ----------
CLARK 2460
KING 5010
MILLER 1310
SQL> select ename,sal,comm,sal+nvl(comm,0)||' RMB' zsal from emp where deptno=30;
ENAME SAL COMM ZSAL
---------- ---------- ---------- --------------------------------------------
ALLEN 1600 300 1900 RMB
WARD 1250 500 1750 RMB
MARTIN 1250 1400 2650 RMB
BLAKE 2850 2850 RMB
TURNER 1500 0 1500 RMB
JAMES 950 950 RMB
3.distinct去除重复的行
SQL> select distinct deptno from emp;
DEPTNO
----------
30
20
10
4.where 条件,限制查询的行数。条件子句里面可以有between..and,in,like,[not]null,比较条件,逻辑条件等
SQL> select ename,sal from emp where sal<1000;
ENAME SAL
---------- ----------
JAMES 950
SMITH 800
SQL> select ename,sal from emp where sal between 300 and 1000;
ENAME SAL
---------- ----------
JAMES 950
SMITH 800
SQL> select ename,sal from emp where sal in(800,950);
ENAME SAL
---------- ----------
JAMES 950
SMITH 800
SQL> select ename,sal from emp where ename like '_A%';
ENAME SAL
---------- ----------
JAMES 950
MARTIN 1250
WARD 1250
SQL> select ename,sal from emp where ename like '%\_%' escape '\';
ENAME SAL
---------- ----------
E%_120
E%_\/121
注释:当使用like查找字符为特殊字符时,必须使用escape指定换码符,换码符相当于转移符。
SQL> select ename,sal from emp where ename like '%\\%' escape '\';
ENAME SAL
---------- ----------
E%_\/121
SQL> select ename,sal,comm from emp where deptno=30 and comm is not null;
ENAME SAL COMM
---------- ---------- ----------
ALLEN 1600 300
WARD 1250 500
MARTIN 1250 1400
TURNER 1500 0
注释:在使用条件的时候,注意优先规则,规则如下:
算术运算符
连字操作
比较操作
is[not]null,like,[not]in
[not]between
not逻辑条件
and逻辑条件
or逻辑条件
但是可以使用()强制改变优先规则,以达到自己运算的目的。
5.order by 排序,asc(升序)|desc(降序).可以为列别名排序,也可以多列排序,多列排序用逗号分隔,先以左边的为准。
SQL> select deptno,ename,sal from emp order by deptno,sal desc;
DEPTNO ENAME SAL
---------- ---------- ----------
10 KING 5000
10 CLARK 2450
10 MILLER 1300
20 FORD 3000
20 SCOTT 3000
20 JONES 2975
20 ADAMS 1100
20 SMITH 800
30 BLAKE 2850
30 ALLEN 1600
30 TURNER 1500
DEPTNO ENAME SAL
---------- ---------- ----------
30 WARD 1250
30 MARTIN 1250
30 JAMES 950
E%_\/121
E%_120
注释:空值是按最大算,如果是字符的话,按照A-Z的升序。asc升序,可以省略。
6.单行函数:
概念:这些函数只对单个行进行操作,清且每行只返回一个结果。
特点:只对一行值进行操作,如有多行值,将分别对多行值进行操作,而不会将多行值作为一个整体进行操作。能够在select,where,order by子句中使用,并且可以嵌套使用。
语法:fun_name(arg1,arg2,....)
常用的有:字符,数字,日期,转换,通用 函数
a.字符函数,包括如下:
大小写处理函数->lower,upper,initcap
字符串函数->concat,substr,length,instr,lpad|rpad,trim,replace
举例:
SQL> select lower('WHAt Is NAmE') from dual;
LOWER('WHATI
------------
what is name
SQL> select upper('WHAt Is NAmE') from dual;
UPPER('WHATI
------------
WHAT IS NAME
SQL> select initcap('WHAt Is NAmE') from dual;
INITCAP('WHA
------------
What Is Name
SQL> select concat('aaa','bdg') from dual;
CONCAT
------
aaabdg
注释:concat连接字符串,等同于||
SQL> select substr('dlfjadlj',4,3) from dual;
SUB
---
jad
SQL> select substr('dlfjadlj',-2,3) from dual;
SU
--
lj
注释:在给定字符串中,从第多少个起(可正可负,正值表示从左往右数第几个开始,负值相反),都是往右取多少个字符
SQL> select length('dlfjadlj') from dual;
LENGTH('DLFJADLJ')
------------------
8
SQL> select length(' ') from dual;
LENGTH('')
----------
1
注释:length换回指定字符串的长度,空格为一个字符串长度。
SQL> select instr('dlfjalfjdjliu;','l',3) from dual;
INSTR('DLFJALFJDJLIU;','L',3)
-----------------------------
6
SQL> select instr('dlfjalfjdjliu;','l',3,2) from dual;
INSTR('DLFJALFJDJLIU;','L',3,2)
-------------------------------
11
SQL> select instr('dlfjalfjdjliu;','l',-5) from dual;
INSTR('DLFJALFJDJLIU;','L',-5)
------------------------------
6
注释:instr 返回指定字符在指定字符串的第几个位置。在这个例子中,dlfjalfjdjliu;为指定字符串,l为指定字符,3,-5表示从第几个字符开始(正数往右数,负数往左数),2表示第几个匹配项。
SQL> select lpad('What is name',6),lpad('What is name',25),lpad('What is name',25,'-') from dual;
LPAD(' LPAD('WHATISNAME',25) LPAD('WHATISNAME',25,'-')
------ ------------------------- -------------------------
What i What is name -------------What is name
SQL> select lpad('What is name',6),lpad('What is name',25),lpad('What is name',25,'-') from dual;
RPAD(' RPAD('WHATISNAME',25) RPAD('WHATISNAME',25,'-')
------ ------------------------- -------------------------
What i What is name What is name - - - - - -
注释:lpad,rpad返回指定长度的字符串,不够长度的用指定字符填充,lpad在左边填充,rpad在右边填充。
SQL> select trim(' aaadddbbbccc ') from dual;
TRIM('AAADDD
------------
aaadddbbbccc
SQL> select trim('c' from 'cccaaadddcccbbbccc') from dual;
TRIM('C'FROM
------------
aaadddcccbbb
SQL> select trim(leading 'c'from'cccaaadddcccbbbccc') from dual;
TRIM(LEADING'C'
---------------
aaadddcccbbbccc
SQL> select trim(trailing 'c'from'cccaaadddcccbbbccc') from dual;
TRIM(TRAILING'C
---------------
cccaaadddcccbbb
SQL> select trim(both 'c'from'cccaaadddcccbbbccc') from dual;
TRIM(BOTH'C'
------------
aaadddcccbbb
注释:trim去掉指定字符串前后的某一指定字符,该字符如果没有指定那么默认是空格。使用leading只去除前面的,trailing只去除后面的,both前后一起去除,可以省略。
SQL> select replace('Jack and JUE','J','B') from dual;
REPLACE('JAC
------------
Back and BUE
SQL> select replace('Jack and JUE','J') from dual;
REPLACE('J
----------
ack and UE
注释:replace替换函数,格式:repalce(c1,c2[,c3]),把指定字符串c1�鹊�c2替换成c3,如果不指定c3就是把c2删除。
b.数字函数
包括 round四舍五入函数
trunc截断函数,指定位数后不论大小都舍去
ceil 取整函数,小数点后有就收为1,全是0不算阿
mod求余函数,也叫求模函数
举例:
SQL> select round(8908.83522,2) from dual;
ROUND(8908.83522,2)
-------------------
8908.84
SQL> select round(8908.83522,3) from dual;
ROUND(8908.83522,3)
-------------------
8908.835
SQL> select trunc(8908.83522,2) from dual;
TRUNC(8908.83522,2)
-------------------
8908.83
SQL> select ceil(8908.03522) from dual;
CEIL(8908.03522)
----------------
8909
SQL> select mod(5,3) from dual;
MOD(5,3)
----------
2
SQL> select mod(5.2,3) from dual;
MOD(5.2,3)
----------
2.2
c.日期函数
日期在每个系统都被分为:世纪,年,月,日,时,分,秒
日期可以加减数字,两个日期可以相减(结果为天数)。date数据类型总是以4位内部数字存储年信息,2位表世纪,2位表年。
常见日期函数:sysdate round trunc months_between add_months next_day last_day
举例:
SQL> select sysdate,current_date from dual;
SYSDATE CURRENT_D
--------- ---------
07-JAN-10 07-JAN-10
SQL> alter session set nls_date_format='mm-dd-yy';
SQL> select sysdate,current_date from dual;
SYSDATE CURRENT_
-------- --------
01-07-10 01-07-10
SQL> select ename,sysdate-hiredate days from emp where deptno=10;
ENAME DAYS
---------- ----------
CLARK 10439.7714
KING 10278.7714
MILLER 10211.7714
SQL> select ename,round(sysdate-hiredate) days from emp where deptno=10;
ENAME DAYS
---------- ----------
CLARK 10440
KING 10279
MILLER 10212
SQL> select ename,trunc(sysdate-hiredate) days from emp where deptno=10;
ENAME DAYS
---------- ----------
CLARK 10439
KING 10278
MILLER 10211
SQL> select ename,months_between(sysdate,hiredate) from emp where deptno=10;
ENAME MONTHS_BETWEEN(SYSDATE,HIREDATE)
---------- --------------------------------
CLARK 342.467339
KING 337.209275
MILLER 335
注释:返回2个指定日期的月份差,师两个日期的大小结果可正可负可零。
SQL> select ename,hiredate,add_months(hiredate,6) from emp where deptno=10;
ENAME HIREDATE ADD_MONT
---------- -------- --------
CLARK 06-09-81 12-09-81
KING 11-17-81 05-17-82
MILLER 01-23-82 07-23-82
注释:指定日期后加n(n为整数)天后的日期
SQL> select sysdate,next_day(sysdate,'monday') from dual;
SYSDATE NEXT_DAY(S
---------- ----------
2010-01-07 2010-01-11
注释:next_mouths(d,n)表示指定日期d后第一个n的日期,其中n为一周中的某一天,n是使用英文还是中文 由nls_language的指来决定。如够是 simplified chinese,那么就可以使用:'星期一'。
SQL> select last_day(sysdate) from dual;
LAST_DAY(S
----------
2010-01-31
注释:last_day指定当月最后一天。
d.转换函数
他包含:隐式类型转换,显式类型转换。当我们需要使用其他的数据类型的时候,我们可以通过转换函数如to_char,to_number,to_date,bin_to_num等进行,这叫显式类型转换,或者可以被oracle服务器自动转换,这叫隐式类型转换。建议使用显示转换意确保SQL语句的可靠性。
举例:
SQL> select to_char('-1000','9999.99'),to_char('-1000','9999.99'),to_char('-1000','$9999.00'),to_char(1000,'00009999.00') from dual;
TO_CHAR( TO_CHAR( TO_CHAR(' TO_CHAR(1000
-------- -------- --------- ------------
-1000.00 -1000.00 -$1000.00 00001000.00
SQL> select to_char(sysdate,'yyyy-fmmm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2010-1-7 19:48:15
注释:这里的fm元素的作用是:删除填补的空,或者前导的零
注释:to_char()函数又分三小类:
(1)字符->字符 将nchar,nvarchar2,clob,nclob转换为varchar2类型(有的地方说的转换为char,那是错的,返回始终是varchar2)
(2)数值->字符 将指定数值n按照执行格式转换为varchar2类型
(3)时间->字符 将时间(data,timestamp,timestamp with time zone)按照指定格式转换为varchar2类型
SQL> select to_char(to_date('2009','yy'),'yyyy-mm-dd') from dual;
TO_CHAR(TO
----------
2009-12-01
SQL> select to_number('FFF','xxxx') from dual; 十六制转换成10进制
TO_NUMBER('FFF','XXXX')
-----------------------
4095
SQL> select to_char('15','xx') from dual; (to_char 是转换成字符,所以可以把十进制转换成十六进制)
TO_
---
f
SQL> select bin_to_num(1,1,0,1) from dual; (把二进制转换成了十进制)
BIN_TO_NUM(1,1,0,1)
-------------------
13
注释:上面三个例子为进制转换
SQL> select to_number('-100.00','9G999D999') from dual;
TO_NUMBER('-100.00','9G999D999')
--------------------------------
-100
SQL> select to_char('-100.00','9G999D9999') from dual;
TO_CHAR('-1
-----------
-100.0000
e.通用函数
他不针对某一种数据类型,他几乎可以对所有数据类型操作,包括空值。
常用的有:nvl,nvl2,nullif,coalesce
举例:
1).nvl 就是把null值转换成 指定字符,不是空值的,则显示本身。
SQL> select ename,comm,nvl(comm,0) from emp where deptno=30;
ENAME COMM NVL(COMM,0)
---------- ---------- -----------
ALLEN 300 300
WARD 500 500
MARTIN 1400 1400
BLAKE 0
TURNER 0 0
2).nvl2
nvl2(exp1,exp2,exp3) exp1不为空 就返回exp2,如果为空 就是返回exp3
SQL> select ename,COMM,nvl2(comm,'ok',sal) from emp;
ENAME COMM NVL2(COMM,'OK',SAL)
---------- ---------- ----------------------------------------
SMITH 800
ALLEN 300 ok
WARD 500 ok
JONES 2975
3).nullif 比较两个值,一样就显示空,不一样就显示本来的值。
SQL> select ename,deptno,nullif(deptno,10) from emp where ename like '%K%';
ENAME DEPTNO NULLIF(DEPTNO,10)
---------- ---------- -----------------
BLAKE 30 30
CLARK 10
KING 10
4).coalesce 沿着coalesce后括号内的参数一直往下找 非空的,非空就显示。
SQL> select ename,comm,sal,coalesce(comm,sal,100) from emp where ename like '%E%';
ENAME COMM SAL COALESCE(COMM,SAL,100)
---------- ---------- ---------- ----------------------
ALLEN 300 1600 300
JONES 2975 2975
BLAKE 2850 2850
TURNER 0 1500 0
7.多表查询
句式:
select <> from tab1,tab2 where tab1.<>=tab.<>
SQL> select ename,loc from emp,dept; 有56行,这是笛卡尔乘积的结果。有很多重复的内容,所以我们需要限制
解决重复内容使用:where限制语句,或者连接语句(等值连接 不等连接 自连接 外连接)
(1)等值连接
等值连接:多个表之间有对应关系,一个表的列与另一个表的列有相同的内容的时候。
eg:
SQL> select ename,loc,sal from emp,dept where emp.deptno=dept.deptno;
注: 等值连接中的select中的列一般建议指定表名,列名。
SQL> select ename,loc,sal,emp.deptno from emp,dept where emp.deptno=dept.deptno;
SQL> select ename,dname,loc,sal from emp,dept where emp.deptno=dept.deptno and loc='NEW YORK';
ENAME DNAME LOC SAL
---------- -------------- ------------- ----------
CLARK ACCOUNTING NEW YORK 2450
KING ACCOUNTING NEW YORK 5000
MILLER ACCOUNTING NEW YORK 1300
SQL> select ename,dname,loc,sal from emp e,dept d where e.deptno=d.deptno and loc='NEW YORK';
注释:表的别名
(2)外连接
显示dept表deptno列的值在emp里面没有的。
SQL> select ename,dname,sal,d.deptno from emp e,dept d where e.deptno(+)=d.deptno; (+放在要显示的表的对方那张表)
(3)自连接
显示上下级关系.
SQL> select e.ename,e.mgr "xj",m.ename "sj" from emp e,emp m where e.mgr=m.empno;
在两个视图下做:用户是scott的会话的编号 进程号。
SQL> desc v$process
SQL> desc v$session
SQL> select sid,pid from v$session s,v$process p where s.paddr=p.addr and s.username='SCOTT';
注意:外连接,自连接 都是等值连接。
(4)不等值连接
就是结果不相等,但是满足某种关系的时候。
SQL> desc salgrade
Name Null? Type
----------------------------------------- -------- ----------------------------
GRADE NUMBER
LOSAL NUMBER
HISAL NUMBER
SQL> select ename,sal,grade from emp e,salgrade s where sal between losal and hisal;(between可以使用大于小于来替换)
****************************************************************************
SQL99下的一些 等值连接 的写法:
SQL> select ename,dname from emp cross join dept;(sql99标准的写法) (cross join 也叫交叉连接 或 笛卡尔乘积)
等于
SQL> select ename,dname from emp,dept;(oracle内部的使用方法,不通用,只能oracle内部使用)
SQL> select ename,dname from emp join dept on (emp.deptno=dept.deptno);
等于
SQL> select ename,dname from emp,dept where emp.deptno=dept.deptno;
SQL> select ename,dname from emp natural join dept;
SQL> select ename,dname from emp join dept using (deptno);
**********************************************************************************
SQL99的 外连接 的写法:
SQL> select ename,dname from dept left outer join emp using (deptno);
SQL> select ename,dname from emp right outer join dept using (deptno);
SQL> select ename,dname from emp right outer join dept on (emp.deptno=dept.deptno);
SQL> select ename,dname from dept right outer join emp on (emp.deptno=dept.deptno);
等于:
SQL> select ename,dname,sal,d.deptno from emp e,dept d where e.deptno(+)=d.deptno;
*********************************************************************************
注意:自连接 没有所谓的SQL99标准 写法了。
8.嵌套函数
他不属于一种单独的函数类型,只是多个查询子句合成一个查询子句。
单行函数可以任意层次嵌套。嵌套函数的计算是从里往外的。
举例:
SQL> select ename,nvl(to_char(mgr),'ld') from emp where ename like '%K%';
ENAME NVL(TO_CHAR(MGR),'LD')
---------- ----------------------------------------
BLAKE 7839
CLARK 7839
KING ld
9.组函数
这些函数能够操作成组的行,每个行组给出一个结果。
(1).avg max min sum count 的使用
公司平均工资,最多,最少,多少个员工,总工资多少(不含奖金):
SQL> select avg(sal),max(sal),min(sal),count(*),sum(sal) from emp where sal is not null;
AVG(SAL) MAX(SAL) MIN(SAL) COUNT(*) SUM(SAL)
---------- ---------- ---------- ---------- ----------
2073.21429 5000 800 14 29025
公司的每个月工资总支出:
SQL> select sum(sal+nvl(comm,0)) from emp;
SUM(SAL+NVL(COMM,0))
--------------------
31225
注意:avg max min 这几个都是忽略空值的,所以计算的时候要使用nvl给空值赋值0。
(2).unique distinct 的使用:忽略重复行
SQL> select count(unique deptno) from emp;
COUNT(UNIQUEDEPTNO)
-------------------
3
SQL> select count(distinct deptno) from emp;
COUNT(DISTINCTDEPTNO)
---------------------
3
(3).分组函数分组语句: -->group by
SQL> select deptno,avg(sal) from emp group by deptno;
DEPTNO AVG(SAL)
---------- ----------
30 1566.66667
20 2175
10 2916.66667
注意:分组函数的列、group by 的列可以出现在select选项中,其他列不允许出现。
(4).限制分组函数的结果 使用 having
SQL> select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
DEPTNO AVG(SAL)
---------- ----------
20 2175
10 2916.66667
注意:这里不能使用where,因为avg(sal)是不存在列(伪列),having 则用在伪列后,一般和group by连用。
问题:获得每年入职的人有多少人??
注:SQL> select sum(decode(to_char(hiredate,'yyyy'),'1980',1,0)) "1980" from emp;
SQL> select to_char(hiredate,'yyyy')as hire,count(*) from emp group by to_char(hiredate,'yyyy');
HIRE COUNT(*)
---- ----------
1987 2
1980 1
1982 1
1981 10
SQL> select sum(decode(to_char(hiredate,'yyyy'),'1980',1,0)) "1980",
2 sum(decode(to_char(hiredate,'yyyy'),'1982',1,0)) "1982" ,
3 sum(decode(to_char(hiredate,'yyyy'),'1981',1,0)) "1981" ,
4 sum(decode(to_char(hiredate,'yyyy'),'1987',1,0)) "1987" from emp;
1980 1982 1981 1987
---------- ---------- ---------- ----------
1 1 10 2
10.子查询
***************************************************************************************************************************
子查询 :select语句里面还有select语句就是子查询,他包含子查询语句 和 主查询语句.外面的叫主查询语句,里面的叫子查询语句。子查询语句必须使用(),()�仁亲硬檠�语句
如果子查询返回的结果是一行的叫单行子查询,结果传递给主查询的时候,如果使用关系运算应该使用单行比较操作符,如= < >
如果子查询返回的结果是多行的叫多行子查询,结果传递给主查询的时候,如果使用关系运算应该使用多行比较操作符,如 in (注意:in走全表不走索引)
********************************************************************************************************************
谁的工资最高;
SQL> select ename,sal from emp where sal=(select max(sal) from emp);
ENAME SAL
---------- ----------
KING 5000
和SCOTT工资一样的:
SQL> select ename,sal from emp where sal=(select sal from emp where ename='SCOTT');
ENAME SAL
---------- ----------
SCOTT 3000
FORD 3000
注意:这个是单行子查询,因为select sal from emp where ename='SCOTT'返回一个值。
显示每个部门最高工资的员工的名字和薪水:
SQL> select ename,sal,deptno from emp where (deptno,sal) in (select deptno,max(sal) from emp group by deptno);
ENAME SAL DEPTNO
---------- ---------- ----------
BLAKE 2850 30
SCOTT 3000 20
KING 5000 10
FORD 3000 20
嵌套子查询(视图):
~~~~~~~~~~~~~
显示每个部门比最低工资的高员工的名字和薪水
SQL> select ename,sal from emp,(select deptno,min(sal) msal from emp group by deptno) s where emp.deptno=s.deptno and sal>msal;
注释;这个一次性的视图,潜入式视图 ,就是把一个子查询语句当成一个临时性的表来使用,而这个表在数据库录不存在。这种方法要学会使用。在子查询语句中min(sal)必须使用别名。
在查询语句里面使用 规则表达式,只能在这些里才能使用;
regexp_like regexp_instr regexp_substr regexp_replace (这个10g以后才有的)
SQL> select ename from emp where regexp_like(ename,'^A');
ENAME
----------
ALLEN
ADAMS
SQL> select ename from emp where regexp_like(ename,'(^A|S)');
ENAME
----------
SMITH
ALLEN
JONES
SCOTT
ADAMS
JAMES
说明:以上这两个句子要是使用like也可以,但是比较麻烦。
SQL> select ename,regexp_substr(ename,'A') from emp;
ENAME REGEXP_SUB
---------- ----------
SMITH
ALLEN A
WARD A
JONES
MARTIN A
BLAKE A
CLARK A
SCOTT
KING
TURNER
ADAMS A
ENAME REGEXP_SUB
---------- ----------
JAMES A
FORD
MILLER
查询1980、1982年入职的员工:
SQL> select * from (select ename,to_char(hiredate,'yyyy' ) hd from emp) where regexp_like(hd,'1980|1982');
ENAME HD
---------- ----
SMITH 1980
MILLER 1982
11.select语句中的2个条件表达式:case ,decode。
比较:case,decode这两个函数可以互相转换,decode更简洁,case更易读。
#.case
语法结构:
case expr when .... then ....
when ....then....
else ...
end
SQL> select ename,deptno,sal,case deptno when 10 then sal+500 when 20 then sal+1001 else sal end as "salj" from emp;
ENAME DEPTNO SAL salj
---------- ---------- ---------- ----------
SMITH 20 800 1801
ALLEN 30 1600 1600
WARD 30 1250 1250
JONES 20 2975 3976
MARTIN 30 1250 1250
BLAKE 30 2850 2850
效果:部门10的工资涨500,部门20的涨1001,其他的不变。
#.decode
语法:
decode(exp,exp_valus1,exp_valus2...)
SQL> select ename,deptno,sal,decode(deptno,10,sal+500,20,sal+1001,sal) as "fkkl" from emp;
ENAME DEPTNO SAL fkkl
---------- ---------- ---------- ----------
SMITH 20 800 1801
ALLEN 30 1600 1600
WARD 30 1250 1250
重点总结:select 多表查询 子查询 分组语句使用分支语句把行转列
(二)DML语句:insert,update,delete
1.insert 在表中插入数据
语法:insert into table_name [(column[,column])] values (value[,value]);
其中,table_name为表名,column为列名,value为列相应的值,values子句为表添加行,一次一行。
在插入时,可以选择只提供部分列的值,未在插入语句中提供值的列,将是空值或由default子句定义的缺省值。
并注意在插入的时候,列的值如果是字符和日期则应该使用单引号,而是数字值就不需要了,用了反而可能发生隐式转换。
举例:
SQL> insert into dept(deptno,dname,loc) values(40,'OPERATIONS','CHINA');
SQL> insert into dept(deptno,dname,loc) values(40,'OPERATIONS'); #隐式插入空值
SQL> insert into dept(deptno,dname,loc) values(40,'OPERATIONS',null); #显式插入空值
也可以使用函数输入特殊值:
SQL> insert into dept(deptno,dname,loc) values(40,'OPERATIONS',sysdate); #这里假设loc是日期类型的,可以使用sysdate函数赋值
还可以插入可输入变量,执行该语句的时候会提示我们输入变量,用于脚本多次插入:
SQL> insert into dept(deptno,dname,loc) values(&deptno1,'OPERATIONS',&loc1);
从另一个表复制插入:
SQL> insert into depttab(deptnoa,dnamea,loca) select deptno,dname,loca from dept;
insert语句中使用子查询:就是使用子查询代替表名,但是他的字段数必须和后面values子句的字段数相等,并且不能遗漏强制为非空的值。
SQL>insert into (select * from dept) values(50,'caiwu',null);
2.update更新表内数据
语法:update table_name set column=value[,column=value] [where condition];
说明:table_name是表名,column是列名,value是列相应的值,condition确定要被更新的行,由列名、表达式、常数、比较操作符组成
切记:用主键来标识一个单行,如果用其他的可能导致意外。
举例:
SQL> update emp set deptno=10 where empno=7934;
如果写成:
SQL> update emp set deptno=10;
那么就会出错,达不到所要结果。
和insert语句一样,update语句也可以使用子查询来做基于另一个表的更新(作为‘赋值’),或者作为表名。
3.delete删除数据
语法:delete [from] table_name [where condition]
说明:table_name 表名,condition是标识删除的行。
delete 可以用来是删除表中的一行或者多行,如果省略where子句将删除表内所有行。
delete操作没有确认提示,但是在事务没有提交(commit)之前是不会被持久化的,如果操作错误,可以通过rollback撤销删除操作,如果提交了,那么只有通过恢复手段找回删除的数据了。
举例:
SQL> delete from emp where empno=8373;
SQL> delete from emp where empno in(8778,8657);
同样,delete里面也可以使用子查询,和删除基于另一个表的行(使用查询语句组为约束值)
SQL> delete from emp where deptno=(select deptno from dept where dname like '%K%');
4.merge 融合语句
他相当于插入,更新语句的综合,通常对俩个表进行操作。要在语句中提供连接那样的条件。sql的扩展包括了merge语句。使用merge需要对目的表有insert和update权限,对源表有select权限.
特性:避免分散更新,提高了性能和易用性,在数据仓库应用中有用。
语法:merge into table_name table_alias
using (table|view|sub_query) alias on (join condition)
when matched then
update set
col1=col_val1,
col2=col_val2
when not matched then
insert (column_list)
values (column_values);
说明:into子句 指定你正在更新或者插入的目的表
using子句 指定数据源要被更新或插入的数据的源,可以是一个表,视图或者子查询。
on子句是一个条件,在此条件上merge操作即可以更新也可以插入。
when matched 通知服务器怎么响应连接条件
<由于时间的原因先写到这里>
说明:create|alter|drop table|view|index 在后面管理表|视图|索引的时候相继出现。
grant|revoke 也将在后面出现。