过滤和排序数据
基本SQL语句格式如下:
select ….
from table1
where ….
order by ….
//where
1 有关日期格式属性修改 常识
NLS_DATE_FORMAT 的默认格式 DD-MON-RR
select sysdate from dual;
NLS_CURRENCY ¥
SQL> select * from v$nls_parameters;
PARAMETER VALUE
---------------------------------------------------------------- -------------------------------------------
---------
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY ¥
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET ZHS16GBK
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY ¥
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
已选择19行。
alter session set NLS_DATE_FORMAT='DD-MON-RR';
alter session set NLS_DATE_FORMAT='yyyy-mm-dd';
—-查询比81年1月1号 入职晚的员工
1 select *
2 from emp
3* where hiredate > '01-1月 -81'
SQL> /
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7839 KING PRESIDENT 17-11月-81 5000 10
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
7900 JAMES CLERK 7698 03-12月-81 950 30
7902 FORD ANALYST 7566 03-12月-81 3000 20
7934 MILLER CLERK 7782 23-1月 -82 1300 10
已选择13行。
------- oracle支持 隐式类型转换 ..eg char ****====>date,除此之外:
-------- 日期转换的函数.....
------ 日期和字符串''
-------日期是格式敏感
select ….
from …..
where col > 30
col in (a,b,c) –特别注意,此处的in只能从括号中已有的值进行选取,并不是表示的范围
col between a and b .. a要小b []
1 查询工资在1000~2000之间的员工信息
select *
from emp
where sal between 1000 and 2000
select *
from emp
where sal >=1000 and sal <=2000
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
7934 MILLER CLERK 7782 23-1月 -82 1300 10
1 select *
2 from emp
3* where sal between 1000 and 200
SQL> /
2 查询10 20号部门的员工信息
查询不是10 20号部门的员工信息
select * from emp
where DEPTNO in (10, 20)
select * from emp
where DEPTNO not in (10, 20)
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 800 20
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7839 KING PRESIDENT 17-11月-81 5000 10
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
7902 FORD ANALYST 7566 03-12月-81 3000 20
7934 MILLER CLERK 7782 23-1月 -82 1300 10
3 in 中是一个集合 …..null
select * from emp
where DEPTNO in (10, 20, null)
select * from emp
where DEPTNO not in (10, 20)
======> in集合中遇见null (in集合和空值在一起...)
=====>in (集合中含有空值 ) 查询结果不受影响
======>not in (集合中含有空值 ) 查询结果受影响
why? .
4 like模糊查询
% 代表零个或多个字符(任意个字符)。
_ 代表一个字符。
查询名字S开头的员工信息
1 select * from emp
2* where ENAME like 'S%'
---''单引号中的字符串是区分大小写的....
SQL> /
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 800 20
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
**查询名字含有4个字母的员工**
select * from emp
where ENAME like '____'
1 select * from emp
2* where ENAME like '____'
SQL> /
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7839 KING PRESIDENT 17-11月-81 5000 10
7902 FORD ANALYST 7566 03-12月-81 3000 20
查询名字含有下划线的员工 (查询的内容含有转义字符)
先往表中插入一行(由于原表中没有名字含有下划线的员工)
insert into emp(empno, ename, sal , DEPTNO) values(1, 'tom_abc', 8000, 10)
select * from emp
where ename like '%\_%' escape '\'
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
1 tom_abc 8000 10
**回避特殊符号的:使用转义符。例如:将[%]转为[\%]、[_]转为[\_],然后再加上[ESCAPE ‘\’] 即可。**
=================ORDER BY子句
1 order by 默认按照排序 从小到大
2 order by后面+列名 表达式 别名 序号
按照薪水,查询员工信息
select *from emp
order by sal
按照年薪,查询员工信息
select empno, ename, sal, sal*12 年薪 from emp
order by 年薪
1 select empno, ename, sal, sal*12 年薪 from emp
2* order by 年薪
SQL> /
EMPNO ENAME SAL 年薪
7369 SMITH 800 9600
7900 JAMES 950 11400
7876 ADAMS 1100 13200
7521 WARD 1250 15000
7654 MARTIN 1250 15000
7934 MILLER 1300 15600
7844 TURNER 1500 18000
7499 ALLEN 1600 19200
7782 CLARK 2450 29400
7698 BLAKE 2850 34200
7566 JONES 2975 35700
7902 FORD 3000 36000
7788 SCOTT 3000 36000
7839 KING 5000 60000
1 tom_abc 8000 96000
****2 order by 遇上空值****
1 任何表达式和null运算都为空
2 null != null (is null )
3 where子句中(in集合和空值在一起...)
4
按照奖金,查询员工信息
1 select empno, ename, comm from emp
2 order by 3 desc
3* nulls last
SQL> /
EMPNO ENAME COMM
---------- ---------- ----------
7654 MARTIN 1400
7521 WARD 500
7499 ALLEN 300
7844 TURNER 0
7782 CLARK
7788 SCOTT
7839 KING
7876 ADAMS
7900 JAMES
7902 FORD
7698 BLAKE
7566 JONES
7934 MILLER
1 tom_abc
7369 SMITH
已选择15行。
3 order by 后面有多个列,
如果多个列中 有desc修饰,只作用于最近的那一列
按照部门排序
select * from emp
order by deptno desc, sal desc;
按照部门和工资排序
select * from emp
order by deptno desc, sal desc
/
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7900 JAMES CLERK 7698 03-12月-81 950 30
7902 FORD ANALYST 7566 03-12月-81 3000 20
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
7369 SMITH CLERK 7902 17-12月-80 800 20
1 tom_abc 8000 10
7839 KING PRESIDENT 17-11月-81 5000 10
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7934 MILLER CLERK 7782 23-1月 -82 1300 10
**
单行函数
**
select ...
from ...
where ....
order by ....
多行函数
SQL> select count(*) from emp;
COUNT(*)
----------
14
字符函数
1 select Lower('Hello') 转小写, upper('hello') 转大写, initcap('hello woRld') 首字母大写
2* from dual
SQL> /
转小 转大 首字母大写
----- ----- -----------
hello HELLO Hello World
select concat('hello', 'world') from dual
SQL> select concat (concat('hello', 'world'), 'cccc') 函数嵌套 from dual;
函数嵌套
--------------
helloworldcccc
CONCAT('HE
----------
helloworld
SUBSTR(a,b) — 从a中第b位 去字符串
substr(a, b, c) 从a中第b位, c个字符….
SQL> select substr('abcdefg1111', 2) 从第二位取子串, substr('abcdefg1111', 2, 4) 取4个字符 from dual;
从第二位取 取4
---------- ----
bcdefg1111 bcde
–length字符数 –lengthb字节数
–一个中文字符,两个字节
SQL> select length('中国abc') 字符数, lengthb('中国abc') 字节数 from dual;
字符数 字节数
---------- ----------
5
SQL> \
SQL> select instr('abcdefg', 'efg') 求子串位置 from dual;
求子串位置
----------
5
SQL> select lpad('abcd', 10, '*') lpad, rpad('abcd', 10, '*') rpad from dual;
LPAD RPAD
---------- ----------
******abcd abcd******
–trim 去掉前后指定的字符,字符可以是空格,也可以不是空格 .
SQL> select trim(‘A’ from ‘ABCDEFg’) from dual;
TRIM('
------
BCDEFg
========数字函数
//2 > 0 表 保留小数点2位
// 0 保留个位
//-1 保留10位
//-1 保留百位 (要看十位 四舍五入)
1 select round(45.926, 2) AA, round(45.926, 1) BB, round(45.926, 0) CC, round(45.926) DD,
2* round(45.926, -1) EE, round(45.926, -2) FF from dual
3 /
AA BB CC DD EE FF
45.93 45.9 46 46 50 0
=========日期
时间的计算…….
oracle数据库中 date包含 日期和时间
mysql 3中数据类型 date time times…..
select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual ;
SQL> select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual ;
TO_CHAR(SYSDATE,'YY
-------------------
2014-10-07 16:34:17
----昨天今天明天
select sysdate-1 昨天, sysdate 今天, sysdate+1 明天 from dual;
select to_char(sysdate-1, 'yyyy-mm-dd hh24:mi:ss') 昨天, sysdate 今天, sysdate+1 明天 from dual;
----查询员工的入职时间,按照 周 月 年 方式显示.....
select (sysdate-hiredate)/7 周, (sysdate-hiredate)/30 月, (sysdate-hiredate)/365 年
from emp;
1 select (sysdate-hiredate)/7 周, (sysdate-hiredate)/30 月, (sysdate-hiredate)/365
2* from emp
SQL> /
周 月 年
---------- ---------- ----------
1763.95625 411.589791 33.8292979
1754.67053 409.423125 33.6512157
1754.38482 409.356458 33.6457363
1748.81339 408.056458 33.538887
1723.24196 402.089791 33.048476
1744.67053 407.089791 33.4594349
1739.09911 405.789791 33.3525856
1433.38482 334.456458 27.4895719
1716.09911 400.423125 32.9114897
1726.09911 402.756458 33.1032705
1428.52768 333.323125 27.3964212
1713.81339 399.889791 32.8676541
1713.81339 399.889791 32.8676541
1706.52768 398.189791 32.7279281
---查询员工的入职时间, 入职月数 ....
select ename, (sysdate-hiredate)/30 估计月, MONTHS_BETWEEN(sysdate, hiredate) 函数计算月
from emp
1 select ename, (sysdate-hiredate)/30 估计月, MONTHS_BETWEEN(sysdate, hiredate) 函数计算月
2* from emp
SQL> /
ENAME 估计月 函数计算月
---------- ---------- ----------
SMITH 411.589872 405.699876
ALLEN 409.423205 403.603102
WARD 409.356539 403.538586
JONES 408.056539 402.183747
MARTIN 402.089872 396.345037
BLAKE 407.089872 401.216005
CLARK 405.789872 399.957941
SCOTT 334.456539 329.63536
KING 400.423205 394.699876
TURNER 402.756539 396.990199
ADAMS 333.323205 328.506328
JAMES 399.889872 394.151489
FORD 399.889872 394.151489
MILLER 398.189872 392.506328
已选择14行。
select next_day(sysdate, '星期六') from dual
SQL> select next_day(sysdate, '星期六') from dual ;
NEXT_DAY(SYSDA
--------------
11-10月-14
==========================数据类型转换==============
select *
2 from emp
3* where hiredate > ‘01-1月 -81’
日期相关类型转换
—比这个日期都要大的08-9月 -81 所有员工信息 按照三种方式实现
select * from emp
where hiredate > '01-1月 -81' --隐式类型转换
select * from emp
where hiredate > to_date('1981-01-01 02:03:04', 'yyyy-mm-dd hh24:mi:ss') --字符串转成日期...显示类型转换
select * from emp
where to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss') > '1981-01-01 02:03:04'
1 select * from emp
2* where hiredate > to_date('1981-01-01 02:03:04', 'yyyy-mm-dd hh24:mi:ss')
SQL> /
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7839 KING PRESIDENT 17-11月-81 5000 10
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
7900 JAMES CLERK 7698 03-12月-81 950 30
7902 FORD ANALYST 7566 03-12月-81 3000 20
====================
数字和字符串转换
–查询员工的薪水:两位小数 本地货币代码 千位符
Y1,250.00
select empno, ename, to_char(sal, ‘L9,999.99’)
from emp;
1 select empno, ename, to_char(sal, 'L9,999.99')
2* from emp
SQL> /
EMPNO ENAME TO_CHAR(SAL,'L9,999
---------- ---------- -------------------
7369 SMITH ¥800.00
7499 ALLEN ¥1,600.00
7521 WARD ¥1,250.00
7566 JONES ¥2,975.00
7654 MARTIN ¥1,250.00
7698 BLAKE ¥2,850.00
7782 CLARK ¥2,450.00
7788 SCOTT ¥3,000.00
7839 KING ¥5,000.00
7844 TURNER ¥1,500.00
7876 ADAMS ¥1,100.00
7900 JAMES ¥950.00
7902 FORD ¥3,000.00
7934 MILLER ¥1,300.00
已选择14行。
把这个字符¥1,250.00,转成数字…..
select to_number(‘¥1,250.00’, ‘L9,999.99’) from dual ;
SQL> select to_number('¥1,250.00', 'L9,999.99') from dual ;
TO_NUMBER('¥1,250.00','L9,999.99')
-----------------------------------
1250
通用函数
=======条件表达式 做报表
-给员工涨工资:总裁 1000 经理:800 其他涨500,
前后工资给列出来
PRESIDENT
MANAGER
if (job == ‘PRESIDENT’)
SAL+1000
else if (job == ‘MANAGER’)
SAL+800
else
SAL+500
CASE expr WHEN comparison_expr1 THEN return_expr1
[WHEN comparison_expr2 THEN return_expr2
WHEN comparison_exprn THEN return_exprn
ELSE else_expr]
END
CASE job when ‘PRESIDENT’ then sal+1000
when ‘MANAGER’ then sal+800
else sal + 500
END
select ename, job, sal 涨前工资,
(
CASE job when ‘PRESIDENT’ then sal+1000
when ‘MANAGER’ then sal+800
else sal + 500
END
)
涨后工资
from emp
ENAME JOB 涨前工资 涨后工资
---------- --------- ---------- ----------
SMITH CLERK 800 1300
ALLEN SALESMAN 1600 2100
WARD SALESMAN 1250 1750
JONES MANAGER 2975 3775
MARTIN SALESMAN 1250 1750
BLAKE MANAGER 2850 3650
CLARK MANAGER 2450 3250
SCOTT ANALYST 3000 3500
KING PRESIDENT 5000 6000
TURNER SALESMAN 1500 2000
ADAMS CLERK 1100 1600
JAMES CLERK 950 1450
FORD ANALYST 3000 3500
MILLER CLERK 1300 1800
已选择14行。
第二种方法
DECODE(col|expression, search1, result1
[, search2, result2,…,]
[, default])
decode(job, ‘PRESIDENT’, sal+10000, ‘MANAGER’, sal+800, sal+500)
select ename, job, sal 涨前工资,
(
decode(job, ‘PRESIDENT’, sal+10000, ‘MANAGER’, sal+800, sal+500)
)
涨后工资
from emp
**
多行函数-分组依据-分组过滤
**
select …..
from ….
where col in ..
col >
col between a and b
order by ….
group by ….
having……
组函数
1
1 select avg(sal), sum(sal), max(sal), min(sal), count(sal)
2* from emp
3 /
AVG(SAL) SUM(SAL) MAX(SAL) MIN(SAL) COUNT(SAL)
---------- ---------- ---------- ---------- ----------
2073.21429 29025 5000 800 14
2--组函数和null在一起.....
求员工的平局奖金
select avg(comm) 方式1, sum(comm)/count(comm) 方式2, sum(comm)/count(*) 方式3
from emp
select count(comm), count(*) from emp ;
SQL> select count(comm), count(*) from emp ;
COUNT(COMM) COUNT(*)
----------- ----------
4 14
*-----组函数自动滤空 .... 组函数忽略空值。*
-----修正组函数的滤空 select count(nvl(comm, 0)), count(*) from emp ;
SQL> select count(nvl(comm, 0)), count(*) from emp;
COUNT(NVL(COMM,0)) COUNT(*)
------------------ ----------
14 14
**分组数据
1 求各个部门的平均工资..**
思想: 需要把各个部门的数据划分....... 10部门 20部门 30部门.....分组...
select deptno, avg(sal)
from emp
group by deptno;
1 select deptno, avg(sal)
2 from emp
3* group by deptno
SQL> /
DEPTNO AVG(SAL)
---------- ----------
30 1566.66667
20 2175
10 2916.66667
2 组函数设计的本意
select a, b, c
from emp
group by a, b, c,d; –ok
select a, b, f
from emp
group by a, b, c,d; –err
——– 1 select检索的列 必须要位于 group by后面的集合列中
2 组函数设计的本意: 必须要在分组数据之上, 进行结果集的检索…. …
注意: group by字句要求: 所有在select中出现的列,都必须在出现在group by分组子句中.
1 select deptno, avg(sal), ename
2 from emp
3* group by deptno
SQL> /
select deptno, avg(sal), ename
*
第 1 行出现错误:
ORA-00979: 不是 GROUP BY 表达式
3在GROUP BY 子句中包含多个列
--按部门 不同的职位 统计平均工资
先按照部门分组,再按照job分组,如果deptno和job一样,就是同一组,然后求平均工资
--求各个部门的,每一个工种的平均工资
select ....
from emp
group by deptno, job
1 select deptno, job, avg(sal), count(deptno)
2 from emp
3 group by deptno, job
4* order by 1
SQL> /
DEPTNO JOB AVG(SAL) COUNT(DEPTNO)
---------- --------- ---------- -------------
10 CLERK 1300 1
10 MANAGER 2450 1
10 PRESIDENT 5000 1
20 ANALYST 3000 2
20 CLERK 950 2
20 MANAGER 2975 1
30 CLERK 950 1
30 MANAGER 2850 1
30 SALESMAN 1400 4
已选择9行。
分组过滤
--查询各个部门的平均工资
1 进一步,查询平均工资大于2000的部门
查询平均工资大于2000的部门
select deptno, avg(sal)
from emp
group by deptno
having avg(sal) > 2000
1 select deptno, avg(sal)
2 from emp
3 group by deptno ---先分组 再过滤
4* having avg(sal) > 2000
SQL> /
DEPTNO AVG(SAL)
---------- ----------
20 2175
10 2916.66667
2 having 和where子句区别
求10号部门的平均工资
—方法1 —先分组 再过滤
select deptno, avg(sal)
from emp
group by deptno
having deptno=10
—方法2 —先过滤在分组…..
select deptno, avg(sal)
from emp
where deptno =10
group by deptno
select deptno, avg(sal)
from emp
where deptno =10
group by deptno
======> 哪一个好….sql优化 方法2好 ….
select * from emp;
select deptno, ename, …, from emp –显示的把所有的列都写出来,速度快,,不需要”翻译”
select *form emp
where (deptno = 10) and (deptno=20) and (deptno=30)
<---------
oracle解析逻辑表达式 的方向….从右向左
**
多表查询
**
select …
from table1, table2
where ….
order by ….
group by ….
having …
笛卡尔积基本原理
两个表如果笛卡尔积运算
1 行数 两个表相乘
2 列数 两个表相加..
1 select count(e.EMPNO)
2 from emp e, dept d
3* where e.deptno = d.deptno
SQL> /
COUNT(E.EMPNO)
--------------
14
SQL> ed
已写入 file afiedt.buf
1 select count(e.EMPNO)
2* from emp e, dept d
3 /
COUNT(E.EMPNO)
--------------
56
等值连接
eg:查询员工信息,员工号,姓名,月薪,部门名称
select e.empno, e.ename, e.sal, d.dname
from emp e, dept d
where e.deptno = d.deptno
EMPNO ENAME SAL DNAME
7369 SMITH 800 RESEARCH
7499 ALLEN 1600 SALES
7521 WARD 1250 SALES
7566 JONES 2975 RESEARCH
7654 MARTIN 1250 SALES
7698 BLAKE 2850 SALES
7782 CLARK 2450 ACCOUNTING
7788 SCOTT 3000 RESEARCH
7839 KING 5000 ACCOUNTING
7844 TURNER 1500 SALES
7876 ADAMS 1100 RESEARCH
7900 JAMES 950 SALES
7902 FORD 3000 RESEARCH
7934 MILLER 1300 ACCOUNTING
不等值连接
eg:查询员工信息,员工号,姓名,月薪, 薪水级别
select e.empno, e.ename, e.sal, s.grade
from emp e, salgrade s
where e.sal>=s.losal and e.sal<=s.hisal
1 select e.empno, e.ename, e.sal, s.grade
2 from emp e, salgrade s
3* where e.sal>=s.losal and e.sal<=s.hisal
SQL> /
EMPNO ENAME SAL GRADE
---------- ---------- ---------- ----------
7369 SMITH 800 1
7900 JAMES 950 1
7876 ADAMS 1100 1
7521 WARD 1250 2
7654 MARTIN 1250 2
7934 MILLER 1300 2
7844 TURNER 1500 3
7499 ALLEN 1600 3
7782 CLARK 2450 4
7698 BLAKE 2850 4
7566 JONES 2975 4
7788 SCOTT 3000 4
7902 FORD 3000 4
7839 KING 5000 5
外连接
eg:按部门统计员工人数: 部门号 部门名称 各部门人数
---思路1: 求各个部门的人数...要把各个部门数据划分开.....要分组.....
2:各部门人数 员工表
=====>因为 部门人数 是由员工表确定的...所以还要检索员工表...
所以需要多表查询
select d.deptno, d.dname, count(e.empno)
from dept d, emp e
where d.deptno = e.deptno (+)
group by d.deptno, d.dname
DEPTNO DNAME COUNT(E.EMPNO)
---------- -------------- --------------
10 ACCOUNTING 3
20 RESEARCH 5
30 SALES 6
---我们的期望 想把40号部门给统计出来...
----40号部门没有被统计出来的原因: 员工表中没有40号部门的员工...d.deptno = e.deptno (d.40 = e.40)
------本质:等值条件不满足...
========>外连接技术出现的原因
+左外连接: +号在..=号的右边,左外连接....
+右外连接: +号在..=号的左边,左外连接....
我想把部门表的所有列都显示出来, 就需要找到部门表..在对方写(+)
1 select d.deptno, d.dname, count(e.empno)
2 from dept d, emp e
3 where d.deptno = e.deptno(+)
4* group by d.deptno, d.dname
SQL> /
DEPTNO DNAME COUNT(E.EMPNO)
---------- -------------- --------------
10 ACCOUNTING 3
40 OPERATIONS 0
20 RESEARCH 5
30 SALES 6
自连接
– 查询员工信息 ,老板信息
显示: *的老板是*
---思路1: 员工信息 查员工表
查老板信息,还要查员工表...
---思路2 员工表的老板 是 老板表的员工
select e.ename, b.ename
from emp e, emp b
where e.mgr = b.empno
select e.ename || '的老板是' || b.ename
from emp e, emp b
where e.mgr = b.empno (+)
E.ENAME||'的老板是'||B.ENAME
----------------------------
SMITH的老板是FORD
ALLEN的老板是BLAKE
WARD的老板是BLAKE
JONES的老板是KING
MARTIN的老板是BLAKE
BLAKE的老板是KING
CLARK的老板是KING
SCOTT的老板是JONES
KING的老板是
TURNER的老板是BLAKE
ADAMS的老板是SCOTT
JAMES的老板是BLAKE
FORD的老板是JONES
MILLER的老板是CLARK
已选择14行。
select e.ename || '的老板是' || nvl (b.ename, '他自己')
from emp e, emp b
where e.mgr = b.empno (+)
E.ENAME||'的老板是'||NVL(B.E
----------------------------
SMITH的老板是FORD
ALLEN的老板是BLAKE
WARD的老板是BLAKE
JONES的老板是KING
MARTIN的老板是BLAKE
BLAKE的老板是KING
CLARK的老板是KING
SCOTT的老板是JONES
KING的老板是他自己
TURNER的老板是BLAKE
ADAMS的老板是SCOTT
JAMES的老板是BLAKE
FORD的老板是JONES
MILLER的老板是CLARK
已选择14行。