第一章SQL
1.Oracle数据库基础
(1).开始>运行>输入:sqlpusw/nolog>确定sqlplus程序
本地连接
-连接方式-conn[ect]yonghuming/口令[AS SYSDBA|AS SYSOPER]
使用Oracle SQLPlus工具进行本地连接
[图片上传失败...(image-e55399-1513146680888)]
(2)常用数据库访问工具
Oracle SQLPlus
Oracle SQLPlus是与oracle进行交互的客户端工具,Oracle数据库软件安装后就可使用,在SQLPlus中,可以运行sqlplus命令与sql语句。
常用SqlPlus命令:
show user;//显示当前进行连接的用户名;
Show parameter db_name;//显示当前操作的数据库名;
Conn[ect] ;//连接数据库
desc[ribe] 对象名;//查看指定对象的详细信息
第二章.编写简单的查询语句
基本SELECT语句语法
SELECT [DISTINCT]{|column|expression [alias],...}
FROM table;
(1)选择列
SQL> SELECT deptno,dname,loc
FROM dept;
结果:DEPTNO DNAME LOC 地方
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
(2)算术运算符
SQL> SELECT ename, sal, sal+300
FROM emp;
(3)算术运算符先级
SQL> SELECT ename, sal, 12sal+100
FROM emp;
结果:ENAME SAL 12*SAL+100
KING 5000 60100
BLAKE 2850 34300
CLARK 2450 29500
JONES 2975 35800
MARTIN 1250 15100
ALLEN 1600 19300
rows selected.
(4)空值NULL
SQL> SELECT ename, job, sal, comm
FROM emp;
结果:ENAME JOB SAL COMM
KING PRESIDENT 5000
BLAKE MANAGER 2850
TURNER SALESMAN 1500 0
rows selected.
(5)列别名
SQL> SELECT ename AS name, sal salary
FROM emp;
SQL> SELECT ename "Name",
sal*12 "Annual Salary"
FROM emp;
(6)连接操作符
SQL> SELECT ename||job AS "Employees"
FROM emp;
结果:Employees
KINGPRESIDENT
BLAKEMANAGER
CLARKMANAGER
JONESMANAGER
MARTINSALESMAN
ALLENSALESMAN
...
rows selected.
(7)原义字符串
SQL> SELECT ename ||' is a '||job
AS "Employee Details"
FROM emp;
结果:Employee Details
KING is a PRESIDENT
BLAKE is a MANAGER
CLARK is a MANAGER
JONES is a MANAGER
MARTIN is a SALESMAN
(8)消除重复行
SQL> SELECT deptno
FROM emp;
结果: DEPTNO
10
30
10
20
rows selected.
(9)显示表的结构
在SQL*Plus中,可以使用DESCRIBE 命令来查看表结构
DESC[RIBE] tablename
第三章.限制数据和对数据排序
(1)选择限定数据行
SELECT [DISTINCT] {*| column | expression [alias], ...}
FROM table
[WHERE condition(s)]; {where子句紧跟在from字句值后}
通常格式为:列名 比较操作符 要比较的值
(2)选择限定数据行
操作符 含义
= 等于
> 大于
= 大于或等于
< 小于
<= 小于或等于
<> 不等
(3) 使用WHERE子句
比较数值型数据
SQL> SELECT ename, job, deptno
FROM emp
WHERE deptno=20;
结果:ENAME JOB DEPTNO
JAMES CLERK 20
SMITH MANAGER 20
ADAMS ANALYST 20
MILLER CLERK 20
(4) 比较字符型数据
SQL> SELECT ename, job, deptno
FROM emp
WHERE job='CLERK';
结果:ENAME JOB DEPTNO
JAMES CLERK 30
SMITH CLERK 20
ADAMS CLERK 20
MILLER CLERK 10
(5) 比较日期型数据
SQL> SELECT ename, job, deptno
FROM emp
WHERE hiredate > '01-1月-85';
结果:ENAME HIREDATE DEPTNO
SCOTT 1987-4-19 20
ADAMS 1987-5-23 20
特殊比较运算符
SQL> SELECT ename, sal
FROM emp
WHERE sal BETWEEN 1000 AND 1500;
结果:ENAME SAL
MARTIN 1250
TURNER 1500
WARD 1250
ADAMS 1100
MILLER 1300
(6) IN运算符
SQL> SELECT empno, ename, sal, mgr
FROM emp
WHERE mgr IN (7902, 7566, 7788);
结果: EMPNO ENAME SAL MGR
--------- ---------- --------- ---------
7902 FORD 3000 7566
7369 SMITH 800 7902
7788 SCOTT 3000 7566
7876 ADAMS 1100 7788
(7) LIKE运算符
SQL> SELECT ename
FROM emp
WHERE ename LIKE 'S%';{%代表零和任何字符}
?与百分号组合使用
SELECT ename
FROM emp
WHERE ename LIKE 'L%';
??可以使用ESCAPE标识符实现对“%”和 “”的查找
SELECT ename,job
FROM emp
WHERE job LIKE 'MAN@_%' ESCAPE '@';
(8) IS NULL 运算符
SELECT ename, mgr
FROM emp
WHERE mgr IS NULL;
结果:ENAME MGR
KING NULL(空值)
(8)逻辑与(AND)
SELECT empno, ename, job, sal
FROM emp
WHERE sal>=1100
AND job='CLERK';
结果:EMPNO ENAME JOB SAL
7876 ADAMS CLERK 1100
7934 MILLER CLERK 1300
(9)逻辑或(OR):
SELECT empno, ename, job, sal
FROM emp
WHERE sal>=1100
OR job='CLERK';
结果:EMPNO ENAME JOB SAL
7839 KING PRESIDENT 5000
7698 BLAKE MANAGER 2850
7782 CLARK MANAGER 2450
7566 JONES MANAGER 2975
7654 MARTIN SALESMAN 1250
7900 JAMES CLERK 950
(10)SELECT ename, job
FROM emp
WHERE job NOT IN ('CLERK','MANAGER','ANALYST');
结果:ENAME JOB
KING PRESIDENT
MARTIN SALESMAN
ALLEN SALESMAN
TURNER SALESMAN
WARD SALESMAN
(11)运算符的优先级
SELECT ename, job, sal
FROM emp
WHERE job='SALESMAN'
OR job='PRESIDENT'
AND sal>1500;
结果:ENAME JOB SAL
KING PRESIDENT 5000
MARTIN SALESMAN 1250
ALLEN SALESMAN 1600
TURNER SALESMAN 1500
WARD SALESMAN 1250
(12)运算符的优先级,使用括号强制改变优先权
SELECT ename, job, sal
FROM emp
WHERE (job='SALESMAN'
OR job='PRESIDENT')
AND sal>1500;
结果:ENAME JOB SAL
KING PRESIDENT 5000
ALLEN SALESMAN 1600
(13)ORDER BY子句
SELECT ename, job, deptno, hiredate
FROM emp
ORDER BY hiredate;
结果:ENAME JOB DEPTNO HIREDATE
SMITH CLERK 20 17-DEC-80
ALLEN SALESMAN 30 20-FEB-81
??按列名降序排序
SELECT ename, job, deptno, hiredate
FROM emp
ORDER BY hiredate DESC;
结果:ENAME JOB DEPTNO HIREDATE
ADAMS CLERK 20 12-JAN-83
SCOTT ANALYST 20 09-DEC-82
MILLER CLERK 10 23-JAN-82
JAMES CLERK 30 03-DEC-81
FORD ANALYST 20 03-DEC-81
KING PRESIDENT 10 17-NOV-81
MARTIN SALESMAN 30 28-SEP-81
???按列别名排序
SELECT empno, ename, sal*12 annsal
FROM emp
ORDER BY annsal;
结果: EMPNO ENAME ANNSAL
7369 SMITH 9600
7900 JAMES 11400
7876 ADAMS 13200
7654 MARTIN 15000
7521 WARD 15000
7934 MILLER 15600
7844 TURNER 18000
????多列参与排序
SELECT ename, deptno, sal
FROM emp
ORDER BY deptno, sal DESC;
结果: ENAME DEPTNO SAL
KING 10 5000
CLARK 10 2450
MILLER 10 1300
FORD 20 3000
?????按结果集列序号排序
SELECT ename, deptno, sal
FROM emp
ORDER BY 2, 3 DESC;
第四章.单行函数
(1)单行函数语法
~变量
~列名
~表达式
(1)大小写转换函数
函数:LOWER('SQL Course')
UPPER('SQL Course')
INITCAP('SQL Course')【列明|表达式】
结果:sql course
SQL COURSE
Sql Course
(2)大小写转换函数
在显示Blake的雇员编号、姓名和部门编号。
第一种:SELECT empno, ename, deptno
FROM emp
WHERE ename = 'blake';
第二种:SELECT empno, ename, deptno
FROM emp
WHERE ename = UPPER('blake');
结果:EMPNO ENAME DEPTNO
7698 BLAKE 30
(3)字符处理函数
第一种:CONCAT(column1|expression1,column2|expression2)
连接两个值 ,等同于||
SUBSTR (column|expression,n1[,n2])
返回第一个参数中,从第n1位开始,长度为n2的子串。
如果n2省略,取第n1位开始的所有字符。
如果n1是负值,表示从第一个参数的后面第abs(n1)位开始向右取长度为n2的子串。
LENGTH(column | expression)
########取字符长度�
第二种:
INSTR(s1,s2,[,n1],[n2])
返回s1中,子串s2从n1开始,第n2次出现的位置。n1,n2默认值为1
LPAD(s1,n1,s2)
返回s1被s2从左面填充到n1长度后的字符串。�
RPAD(s1,n1,s2)
返回s1被s2从右面填充到n1长度后的字符串。�
TRIM:去除字符串头部或尾部(头尾)的字符�格式:TRIM(leading | trailing | both trim_character From trim_source)
REPLACE(s1,s2,s3)
把s1中的s2用s3替换。�
第三种查询
SELECT ename, CONCAT (ename, job), LENGTH(ename),
INSTR(ename, 'A')
FROM emp
WHERE SUBSTR(job,1,5) = 'SALES';
结果: ENAME CONCAT(ENAME,JOB) LENGTH(ENAME) INSTR(ENAME,'A')
-------------------
MARTIN MARTINSALESMAN 6 2
ALLEN ALLENSALESMAN 5 1
TURNER TURNERSALESMAN 6 0
WARD WARDSALESMAN 4 2
(4) SELECT ROUND(45.923,2),
ROUND(45.923,0),
ROUND(45.923,-1)
FROM DUAL;
结果:ROUND(45.923,2) ROUND(45.923,0) ROUND(45.923,-1)
--------------
45.92 46 50
(5) TRUNC函数
SELECT TRUNC(45.923,2), TRUNC(45.923),
TRUNC(45.923,-1)
FROM DUAL;
结果:TRUNC(45.923,2) TRUNC(45.923) TRUNC(45.923,-1)
-------------
45.92 45 40
(6) MOD函数
SELECT ROUND(45.923,2), ROUND(45.923,0),
ROUND(45.923,-1)
FROM DUAL;
结果:ROUND(45.923,2) ROUND(45.923,0) ROUND(45.923,-1)
--------------
45.92 46 50
(6)TRUNC函数
SELECT TRUNC(45.923,2), TRUNC(45.923),
TRUNC(45.923,-1)
FROM DUAL;
结果:
TRUNC(45.923,2) TRUNC(45.923) TRUNC(45.923,-1)
-------------
45.92 45 40
(7)计算工作为SALESMAN的雇员的月薪和奖金相除后的余数。
SELECT ename, sal, comm, MOD(sal, comm)
FROM emp
WHERE job = 'SALESMAN';
结果:ENAME SAL COMM MOD(SAL,COMM)
MARTIN 1250 1400 1250
ALLEN 1600 300 100
TURNER 1500 0 1500
WARD 1250 500 250
(8)日期的运算
SELECT ename, (SYSDATE-hiredate)/7 WEEKS
FROM emp
WHERE deptno = 10;
结果:ENAME WEEKS
---------- ---------
KING 830.93709
CLARK 853.93709
MILLER 821.36566
(9)常用日期函数
SELECT ename, sal, MONTHS_BETWEEN(SYSDATE,hiredate) months
FROM emp
ORDER BY months
?ADD_MONTHS 函数演示——查询82年后入职的员工转正日期,按照3个月试用期考虑
SELECT ename, sal, hiredate, ADD_MONTHS(hiredate,3) new_date
FROM emp
WHERE hiredate>'01-1月-82';
??1~NEXT_DAY 函数演示——返回在02-2月-06之后的下一个周一是什么日期。
SELECT NEXT_DAY('02-2月-06','星期一') NEXT_DAY
FROM DUAL;
2~LAST_DAY 函数演示——返回06年2月2日所在月份的最后一天。
SELECT LAST_DAY('02-2月-06') "LAST DAY"
FROM DUAL;
3~ROUND函数演示——查询81年入职的员工姓名,入职日期按月四舍五入的日期。
SELECT empno, hiredate,
ROUND(hiredate, 'MONTH')
FROM emp
WHERE SUBSTR(hiredate,-2,2)=‘81';
4~TRUNC 函数演示——查询81年入职的员工姓名,入职日期按月截断的日期。
SELECT empno, hiredate, TRUNC(hiredate, 'MONTH')
FROM emp
WHERE SUBSTR(hiredate,-2,2)=‘81';
(10)常用日期函数-EXTRACT 函数语法
EXTRACT ([YEAR] [MONTH][DAY]
FROM [日期类型表达式])
1~.部门编号是10的部门中所有员工入职月份。
SELECT ename, hiredate,
EXTRACT (MONTH FROM HIREDATE) MONTH
FROM emp
WHERE deptno= 10;
7.转换函数
通常是在字符类型、日期类型、数值类型之间进行显式转换。主要有3个显式转换函数:
TO_CHAR
TO_NUMBER
TO_DATE
(1)TO_CHAR 用于日期型
SELECT ename,
TO_CHAR(hiredate, 'DD Month YYYY') HIREDATE
FROM emp;
结果:ENAME HIREDATE
---------- -----------------
KING 17 November 1981
BLAKE 1 May 1981
CLARK 9 June 1981
JONES 2 April 1981
MARTIN 28 September 1981
ALLEN 20 February 1981
第五章 多表连接
(1)什么是连接
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2;
(2)笛卡尔积的写法
SELECT emp.empno, emp.ename, emp.deptno,� dept.deptno, dept.loc
FROM emp, dept;
(3)用等值连接检索数据
SELECT emp.empno, emp.ename, emp.deptno,� dept.deptno, dept.loc
FROM emp, dept
WHERE emp.deptno=dept.deptno;
结果:EMPNO ENAME DEPTNO DEPTNO LOC
----- ------ ------ ------ ---------
7839 KING 10 10 NEW YORK
7698 BLAKE 30 30 CHICAGO
7782 CLARK 10 10 NEW YORK
7566 JONES 20 20 DALLAS
(4)使用AND运算符增加其它查询条件
SELECT emp.empno, emp.ename, emp.deptno,�
dept.deptno, dept.loc
FROM emp, dept
WHERE emp.deptno=dept.deptno and loc= ‘NEW YORK’;
结果:EMPNO ENAME DEPTNO DEPTNO LOC
7839 KING 10 10 NEW YORK
7782 CLARK 10 10 NEW YORK
(5)通过使用表的别名来简化查询语句
SELECT emp.empno, emp.ename, emp.deptno,
dept.deptno, dept.loc
FROM emp, dept
WHERE emp.deptno=dept.deptno;
(6)查询每个顾客都订购了哪些商品
SELECT c.name,o.itemid
FROM customer c, order o,item i
WHERE c.custid = o.custid and o.ordid = i.ordid;
*[多表连接给每个表自己定义个语句来查找]
(7)非等值连接的数据检索
查询每个员工的姓名,工资,工资等级
SELECT e.ename, e.sal, s.grade
FROM emp e, salgrade s
WHERE e.sal
BETWEEN s.losal AND s.hisal;
结果:ENAME SAL GRADE
JAMES 950 1
SMITH 800 1
SMITH 1100 1
(8)外部连接
查询所有雇员姓名,部门编号,部门名称,包括没有员工的部门也要显示出来
SELECT e.ename, d.deptno, d.dname
FROM emp e, dept d
WHERE e.deptno(+) = d.deptno
ORDER BY e.deptno;
结果:ENAME DEPTNO DNAME
---------- --------- -------------
KING 10 ACCOUNTING
CLARK 10 ACCOUNTING
(9)自身连接
SELECT worker.ename||' leader is '||manager.ename
FROM emp worker, emp manager
WHERE worker.mgr = manager.empno;
两种解决方法:WORKER.ENAME||'leader is'||MANAG
-------------------------------
BLAKE leader is KING
CLARK leader is KING
JONES leader is KING
(10)交叉连接
交叉连接会产生连个表的交叉乘积,和两个表之间的笛卡尔积是一样的;
使用CROSS JOIN 子句完成。
SELECT emp.empno,emp.ename,emp.sal,emp.deptno,dept.loc
FROM emp
CROSS JOIN dept;
(10)自然连接
SELECT empno,ename,sal,deptno,loc
FROM emp
NATURAL JOIN dept;
(11)USING子句
SELECT e.ename,e.ename,e.sal,deptno,d.loc
FROM emp e JOIN dept d USING (deptno)
WHERE deptno = 20 ;
(12)ON子句
SELECT e.empno, e.ename, e.deptno, d.deptno, d.loc
FROM emp e
JOIN dept d
ON (e.deptno = d.deptno);
(13)左外连接
左外连接以FROM子句中的左边表为基表,该表所有行数据按照连接条件无论是否与右边表能匹配上,都会被显示出来。
SELECT e.ename,e.deptno,d.loc
FROM emp e
LEFT OUTER JOIN dept d
ON (e.deptno = d.deptno);
(14)右外连接 右外连接以FROM子句中的右边表为基表,该表所有行数据按照连接条件无论是否与左边表能匹配上,都会被显示出来。
SELECT e.ename,e.deptno,d.loc
FROM emp e
RIGHT OUTER JOIN dept d
ON (e.deptno = d.deptno);
(15)全外链接
全外连接返回两个表等值连接结果,以及两个表中所有等值连接失败的记录
SELECT e.ename,e.deptno,d.loc
FROM emp e
FULL OUTER JOIN dept d
ON (e.deptno = d.deptno);
6.多组函数
(1)分组函数
有五种函数(MIN,MAX,SUM,AVG,COUNT)
(2)MIN函数和MAX函数
MIN和MAX函数主要是返回每组的最小值和最大值
查询入职日期最早和最晚的日期
SELECT MIN(hiredate), MAX(hiredate)
FROM emp;
(3)SUM函数和AVG函数
SUM和AVG函数分别返回每组的总和及平均值查询职位以SALES开头的所有员工平均工资、最低工资、最高工资、工资和
SELECT AVG(sal), MAX(sal),
MIN(sal), SUM(sal)
FROM emp
WHERE job LIKE 'SALES%';
(4)COUNT函数
COUNT():返回表中满足条件的行记录数
查询部门30有多少个员工
SELECT COUNT()
FROM emp
WHERE deptno = 30;
(5)组函数中DISTINCT
查询有员工的部门数量
SELECT COUNT(DISTINCT deptno)
FROM emp;
(6)分组函数中空值处理
除了COUNT(*)之外
SELECT AVG(comm)
FROM EMP
(7)在分组函数中使用NVL函数
SELECT AVG(NVL(comm,0))
FROM emp;
(8)用GROUP BY子句创建数据组
SELECT column, group_function(column)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];
举例:查询每个部门的编号,平均工资
SELECT deptno, AVG(sal)
FROM emp
GROUP BY deptno;
?GROUP BY 所指定的列并不是必须出现在SELECT
SELECT AVG(sal)
FROM emp
GROUP BY deptno;
??按多列分组的GROUP BY子句
查询每个部门每个岗位的工资总和
SELECT deptno, job, sum(sal)
FROM emp
GROUP BY deptno, job;
结果:DEPTNO JOB SUM(SAL)
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
20 ANALYST 6000
20 CLERK 1900
(9)使用组函数的非法的查询
不能在 WHERE子句中限制组,可以通过 HAVING 子句限制组
SELECT deptno, max(sal)
FROM emp
WHERE max(sal) > 2900
GROUP BY deptno;
(10)用 HAVING Clause子句排除组结果
使用 HAVING 子句限制组与 HAVING 子句匹配的结果才输出
SELECT column, group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
列子:查询每个部门最高工资大于2900的部门编号,最高工资
SELECT deptno, max(sal)
FROM emp
GROUP BY deptno
HAVING max(sal)>2900;
(11)使用HAVING子句
SELECT job, SUM(sal) PAYROLL
FROM emp
WHERE job NOT LIKE 'SALES%'
GROUP BY job
ORDER BY SUM(sal);
结果:JOB PAYROLL
--------- ---------
ANALYST 6000
MANAGER 8275
(12)SELECT语句的执行过程
ELECT deptno,job,avg(sal)
FROM emp
WHERE job in ('SALESMAN','MANAGER','CLERK')
GROUP BY deptno,job
HAVING avg(sal)>1000
ORDER BY 3 DESC;
结果:DEPTNO JOB AVG(SAL)
20 MANAGER 2975
30 MANAGER 2850
10 MANAGER 2450
30 SALESMAN 1400
10 CLERK 1300
(13)组函数和多表连接
查询每个部门的部门编号、部门名称、部门人数
SELECT e.deptno,d.dname,count(empno)
FROM emp e,dept d
WHERE e.deptno = d.deptno
GROUP BY e.deptno;
改正错误
SELECT e.deptno,d.dname,count(empno)
FROM emp e,dept d
WHERE e.deptno = d.deptno
GROUP BY e.deptno,d.dname
(14)显示平均薪水的最大值
SELECT max(avg(sal))
FROM emp
GROUP BY deptno;
结果:MAX(AVG(SAL))
-------------
2916.6667