数据库编程2 Oracle 过滤 函数 分组 外连接 自连接
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库编程2 Oracle 过滤 函数 分组 外连接 自连接相关的知识,希望对你有一定的参考价值。
【本文谢绝转载原文来自http://990487026.blog.51cto.com】
续:数据库编程1 Oracle 过滤 函数 分组 外连接 自连接
where like模糊查询,查询员工姓名是4个字母
SQL> select * from emp where ename like ‘____‘; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 7839 KING PRESIDENT 1981-11-17 5000 10 7902 FORD ANALYST 7566 1981-12-03 3000 20 SQL>
where like模糊查询,转义字符
SQL> set linesize 59 SQL> desc emp; 名称 是否为空? 类型 ---------------------------- -------- -------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) SQL> 插入一条新的内容: SQL> insert into emp(empno,ename,sal,deptno) values(1,‘tom_abc‘,8000,10); 已创建 1 行。 查看插入的结果: SQL> set linesize 199 SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 1980-12-17 800 20 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 7566 JONES MANAGER 7839 1981-04-02 2975 20 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 7698 BLAKE MANAGER 7839 1981-05-01 2850 30 7782 CLARK MANAGER 7839 1981-06-09 2450 10 7788 SCOTT ANALYST 7566 1987-04-19 3000 20 7839 KING PRESIDENT 1981-11-17 5000 10 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 7876 ADAMS CLERK 7788 1987-05-23 1100 20 7900 JAMES CLERK 7698 1981-12-03 950 30 7902 FORD ANALYST 7566 1981-12-03 3000 20 7934 MILLER CLERK 7782 1982-01-23 1300 10 1 tom_abc 8000 10 已选择15行。 SQL> select * from emp where ename like ‘%\_%‘ escape ‘\‘; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- 1 tom_abc 8000 10 SQL>
where order by 工资排序,默认升序
SQL> select * from emp order by sal; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 1980-12-17 800 20 7900 JAMES CLERK 7698 1981-12-03 950 30 7876 ADAMS CLERK 7788 1987-05-23 1100 20 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 7934 MILLER CLERK 7782 1982-01-23 1300 10 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 7782 CLARK MANAGER 7839 1981-06-09 2450 10 7698 BLAKE MANAGER 7839 1981-05-01 2850 30 7566 JONES MANAGER 7839 1981-04-02 2975 20 7902 FORD ANALYST 7566 1981-12-03 3000 20 7788 SCOTT ANALYST 7566 1987-04-19 3000 20 7839 KING PRESIDENT 1981-11-17 5000 10 1 tom_abc 8000 10 已选择15行。
where order by 别名
SQL> select empno,ename,sal,sal*12 年薪 from emp order by 年薪; 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 已选择15行。
order by 遇到null
1,任何表达式与null运算都为空
2,null!=null
nulls last 把null放在最后
SQL> select empno,ename,sal,comm 奖金 from emp order by 4 desc; EMPNO ENAME SAL 奖金 ---------- -------------------- ---------- ---------- 7369 SMITH 800 7788 SCOTT 3000 7934 MILLER 1300 7902 FORD 3000 7900 JAMES 950 7566 JONES 2975 7698 BLAKE 2850 7782 CLARK 2450 1 tom_abc 8000 7839 KING 5000 7876 ADAMS 1100 7654 MARTIN 1250 1400 7521 WARD 1250 500 7499 ALLEN 1600 300 7844 TURNER 1500 0 已选择15行。 SQL> select empno,ename,sal,comm 奖金 from emp order by 4 desc nulls last; EMPNO ENAME SAL 奖金 ---------- -------------------- ---------- ---------- 7654 MARTIN 1250 1400 7521 WARD 1250 500 7499 ALLEN 1600 300 7844 TURNER 1500 0 1 tom_abc 8000 7839 KING 5000 7876 ADAMS 1100 7900 JAMES 950 7902 FORD 3000 7934 MILLER 1300 7782 CLARK 2450 7698 BLAKE 2850 7566 JONES 2975 7369 SMITH 800 7788 SCOTT 3000 已选择15行。 SQL>
order修饰多个列,desc的作用范围只是最近的哪一个!
SQL> select * from emp order by deptno desc, sal desc; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- 7698 BLAKE MANAGER 7839 1981-05-01 2850 30 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 7900 JAMES CLERK 7698 1981-12-03 950 30 7788 SCOTT ANALYST 7566 1987-04-19 3000 20 7902 FORD ANALYST 7566 1981-12-03 3000 20 7566 JONES MANAGER 7839 1981-04-02 2975 20 7876 ADAMS CLERK 7788 1987-05-23 1100 20 7369 SMITH CLERK 7902 1980-12-17 800 20 1 tom_abc 8000 10 7839 KING PRESIDENT 1981-11-17 5000 10 7782 CLARK MANAGER 7839 1981-06-09 2450 10 7934 MILLER CLERK 7782 1982-01-23 1300 10 已选择15行。
count函数
SQL> select * from emp ; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 1980-12-17 800 20 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 7566 JONES MANAGER 7839 1981-04-02 2975 20 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 7698 BLAKE MANAGER 7839 1981-05-01 2850 30 7782 CLARK MANAGER 7839 1981-06-09 2450 10 7788 SCOTT ANALYST 7566 1987-04-19 3000 20 7839 KING PRESIDENT 1981-11-17 5000 10 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 7876 ADAMS CLERK 7788 1987-05-23 1100 20 7900 JAMES CLERK 7698 1981-12-03 950 30 7902 FORD ANALYST 7566 1981-12-03 3000 20 7934 MILLER CLERK 7782 1982-01-23 1300 10 1 tom_abc 8000 10 已选择15行。 SQL> select count(*) from emp ; COUNT(*) ---------- 15
字符函数
大小写转换函数
LOWER
UPPER
INITCAP
SQL> select lower(‘HEllo‘)转小写,upper(‘hello‘)转大写,initcap(‘hello WORLD‘)首字母大写 from dual; 转小写 转大写 首字母大写 ---------- ---------- ---------------------- hello HELLO Hello World ============================================== 字符串连接: SQL> select concat(‘Hello‘,‘ haha‘) from dual; CONCAT(‘HELLO‘,‘HAHA -------------------- Hello haha
函数嵌套:
SQL> select concat(‘qqqqqqqqqqq ‘, concat(‘Hello‘,‘ haha‘)) from dual; CONCAT(‘QQQQQQQQQQQ‘,CONCAT(‘HELLO‘,‘HAHA‘)) -------------------------------------------- qqqqqqqqqqq Hello haha
substr(a,b) 从a中第b位开始取字符串:
substr(a,b,c) 从a中第b位开始取c个字符:
SQL> select substr(‘1234567890‘,2) , substr(‘1234567890‘,4,4) from dual; SUBSTR(‘1234567890 SUBSTR(‘ ------------------ -------- 234567890 4567
length 字符数
lengthb 字节数
SQL> select length(‘中国abc‘) 字符数,lengthb(‘中国abc‘) from dual; 字符数 LENGTHB(‘中国ABC‘) ---------- ------------------ 5 9 因为从上面可以看出我们的系统是字符是UTF
instr求子串的位置;
SQL> select instr(‘123456‘,‘345‘) from dual; INSTR(‘123456‘,‘345‘) --------------------- 3
lpad,rpad左填充右填充:
SQL> select lpad(‘abcd‘,10,‘*‘),rpad(‘1234‘,10,‘@‘) from dual; LPAD(‘ABCD‘,10,‘*‘) RPAD(‘1234‘,10,‘@‘) -------------------- -------------------- ******abcd [email protected]@@@@@
trim去除前后指定字符:
SQL> select trim(‘A‘ from ‘AB1231342141412A‘) from dual; TRIM(‘A‘FROM‘AB1231342141412 ---------------------------- B1231342141412
replace 字符串替换
SQL> select replace (‘111222333444‘,‘222‘,‘hahahaa‘) from dual; REPLACE(‘111222333444‘,‘222‘,‘HA -------------------------------- 111hahahaa333444
round 四舍五入
参数2大于0 表保留小数点位数
参数2等于0 表保留小数点到个位
参数2等于-1 表保留小数点到十位
参数2等于-2 表保留小数点到百位
SQL> select round(45.4666,2) from dual; ROUND(45.4666,2) ---------------- 45.47 SQL> select round(45.4666,0) from dual; ROUND(45.4666,0) ---------------- 45 SQL> select round(45.4666,-1) from dual; ROUND(45.4666,-1) ----------------- 50 SQL> select round(145.7266,-2) from dual; ROUND(145.7266,-2) ------------------ 100
tuec截断函数
SQL> select trunc(145.7266,2) from dual; TRUNC(145.7266,2) ----------------- 145.72
mod求余函数
SQL> select mod(145,100) from dual; MOD(145,100) ------------ 45
2,时间处理函数
to_char格式化输出:
SQL> select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss‘) from dual; TO_CHAR(SYSDATE,‘YYYY-MM-DDHH24:MI:SS‘ -------------------------------------- 2016-08-25 11:32:17 SQL> select to_char(sysdate-1,‘yyyy-mm-dd hh24:mi:ss‘) 昨天 from dual; 昨天 -------------------------------------- 2016-08-24 11:34:44 SQL> select to_char(sysdate+1,‘yyyy-mm-dd hh24:mi:ss‘) 明天 from dual; 明天 -------------------------------------- 2016-08-26 11:35:18
两个日期相减,返回日期之间相差的天数
SQL> select ename , (sysdate-hiredate) from emp; ENAME (SYSDATE-HIREDATE) -------------------- ------------------ SMITH 13035.495 ALLEN 12970.495 WARD 12968.495 JONES 12929.495 MARTIN 12750.495 BLAKE 12900.495 CLARK 12861.495 SCOTT 10721.495 KING 12700.495 TURNER 12770.495 ADAMS 10687.495 JAMES 12684.495 FORD 12684.495 MILLER 12633.495 tom_abc 已选择15行。
精确显示员工入职月数,时间运算months_between
SQL> select ename , (sysdate-hiredate)/30 估计月 ,months_between(sysdate,hiredate) 函数计算月 from emp; ENAME 估计月 函数计算月 -------------------- ---------- ---------- SMITH 434.522107 428.279459 ALLEN 432.355441 426.182684 WARD 432.288774 426.118168 JONES 430.988774 424.76333 MARTIN 425.022107 418.92462 BLAKE 430.022107 423.795588 CLARK 428.722107 422.537523 SCOTT 357.388774 352.214943 KING 423.355441 417.279459 TURNER 425.688774 419.569781 ADAMS 356.255441 351.08591 JAMES 422.822107 416.731072 FORD 422.822107 416.731072 MILLER 421.122107 415.08591 tom_abc 已选择15行。
add_months()向指定的日期中加若干的月数
next_day();下一个指定的日期
SQL> select next_day(sysdate,‘星期六‘) from dual; NEXT_DAY(SYSDA -------------- 27-8月 -16
3,数据类型转换:
3,1隐式转换,字符串转日期
SQL> select * from emp where hiredate >‘01-1月 -81‘; 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行。
3,1显示转换,字符串转日期
SQL> select * from emp where hiredate > to_date(‘1981-01-01 12:30:55‘,‘yyyy-mm-dd hh24:mi:ss‘); 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行。
字符串与字符串比较
SQL> select * from emp where to_char(hiredate,‘yyyy-mm-dd hh24:mi:ss‘) > ‘1981-01-01 12:30:55‘; 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行。
to_char()对数字转字符
9 数字
0 零
$ 美元
L 本地货币符号
.小数点
,千位符
SQL> select empno,ename,to_char(sal,‘L9,999.99‘) from emp; EMPNO ENAME TO_CHAR(SAL,‘L9,999.99‘) ---------- -------------------- ---------------------------- 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 1 tom_abc ¥8,000.00 已选择15行。
to_number()字符转数字
SQL> select to_number(‘¥8,000.00‘,‘L9,999.99‘) from dual; TO_NUMBER(‘¥8,000.00‘,‘L9,999.99‘) ----------------------------------- 8000
4,通用函数
nvl2(a,b,c)当a为null时返回c,否则返回b
SQL> select sal ,sal*12+nvl2(comm,comm,0) 年收入 from emp; SAL 年收入 ---------- ---------- 800 9600 1600 19500 1250 15500 2975 35700 1250 16400 2850 34200 2450 29400 3000 36000 5000 60000 1500 18000 1100 13200 950 11400 3000 36000 1300 15600 8000 96000 已选择15行。
nullif(a,b)当a,b相等时返回NULL,否则返回a
SQL> select nullif(‘abc‘,‘abcd‘) from dual; NULLIF ------ abc SQL> select nullif(‘abc‘,‘abc‘) from dual; NULLIF ------ SQL>
案例:总裁涨1000,经理涨800,其他涨500
方法1,SQL规范方法:
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 tom_abc 8000 8500 已选择15行。
方法2:Oracle专有方法
select ename,job,sal 涨前工资, ( decode(job,‘PERMANENT‘,sal+1000,‘MANAGER‘,sal+800,sal+500) ) 涨工资后 from emp; ----------------------------------------------------- SQL> select ename,job,sal 涨前工资, 2 ( 3 decode(job,‘PERMANENT‘,sal+1000,‘MANAGER‘,sal+800,sal+500) 4 ) 5 涨工资后 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 5500 TURNER SALESMAN 1500 2000 ADAMS CLERK 1100 1600 JAMES CLERK 950 1450 FORD ANALYST 3000 3500 MILLER CLERK 1300 1800 tom_abc 8000 8500 已选择15行。
组函数:
SQL> select avg(sal),sum(sal),max(sal),min(sal),count(sal) from emp; AVG(SAL) SUM(SAL) MAX(SAL) MIN(SAL) COUNT(SAL) ---------- ---------- ---------- ---------- ---------- 2468.33333 37025 8000 800 15 SQL>
组函数与null在一起
SQL> select avg(comm),sum(comm),max(comm),min(comm),count(comm) from emp; AVG(COMM) SUM(COMM) MAX(COMM) MIN(COMM) COUNT(COMM) ---------- ---------- ---------- ---------- ----------- 550 2200 1400 0 4 SQL>
组函数会自动过滤空值:
SQL> select avg(comm) ,sum(comm)/count(comm) ,sum(comm)/count(*) from emp; AVG(COMM) SUM(COMM)/COUNT(COMM) SUM(COMM)/COUNT(*) ---------- --------------------- ------------------ 550 550 146.666667 SQL> select count(comm) ,count(*) from emp; COUNT(COMM) COUNT(*) ----------- ---------- 4 15 修正: SQL> select count(nvl(comm,0)) ,count(*) from emp; COUNT(NVL(COMM,0)) COUNT(*) ------------------ ---------- 15 15
分组数据:
求出各个部门的平均工资:
SQL> select deptno,avg(sal) from emp group by deptno; DEPTNO AVG(SAL) ---------- ---------- 30 1566.66667 20 2175 10 4187.5 SQL>
group by 注意:
select a,c,b from tab group by a,b,c,d; --ok
select a,c,f from tab group by a,b,c,d; --err
1,select检索的列必须位于group by后面的集合中
2,组函数设计的本意:必须要在分组数据之上进行结果集合的数据检索.
标准错误:
SQL> select deptno,avg(sal),ename from emp group by deptno; select deptno,avg(sal),ename from emp group by deptno * 第 1 行出现错误: ORA-00979: 不是 GROUP BY 表达式
分组最难的地方:
求出各个部门中的每种职位 平均工资
SQL> select deptno,job,avg(sal),count(deptno) from emp group by deptno,job order by 1; DEPTNO JOB AVG(SAL) COUNT(DEPTNO) ---------- ------------------ ---------- ------------- 10 CLERK 1300 1 10 MANAGER 2450 1 10 PRESIDENT 5000 1 10 8000 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 已选择10行。
having 分组过滤:
查询各个部门的平均工资大于2000的部门:
面试:[查询平均工资大于2000的部门]
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。
SQL> select deptno ,avg(sal) from emp group by deptno having avg(sal) >2000; DEPTNO AVG(SAL) ---------- ---------- 20 2175 10 4187.5
求10号部门的平均工资的两种方法:where having
1,先分组再过滤
SQL> select deptno,avg(sal) from emp group by deptno having deptno=10; DEPTNO AVG(SAL) ---------- ---------- 10 4187.5
2,先过滤再分组
SQL> select deptno,avg(sal) from emp where deptno=10 group by deptno; DEPTNO AVG(SAL) ---------- ---------- 10 4187.5
SQL优化问题:
select * from emp;
select deptno,ename,......from emp --显式的把所有的列都写出来,速度快,不需要‘翻译‘
select *from emp
where (deptno=10) and (deptno=20) and (deptno=30)
Oracle解析方向,从右到左,和C语言的printf函数差不多
多表查询:
SQL> select count(e.empno) from emp e,dept d; COUNT(E.EMPNO) -------------- 60 SQL> select count(e.empno) from emp e,dept d where e.deptno=d.deptno; COUNT(E.EMPNO) -------------- 15
[等值连接],显示员工信息,员工号,姓名,月薪
SQL> select ename,empno,sal,dept.dname from emp,dept where emp.deptno = dept.deptno; ENAME EMPNO SAL DNAME -------------------- ---------- ---------- ---------------------------- CLARK 7782 2450 ACCOUNTING tom_abc 1 8000 ACCOUNTING KING 7839 5000 ACCOUNTING MILLER 7934 1300 ACCOUNTING JONES 7566 2975 RESEARCH SMITH 7369 800 RESEARCH SCOTT 7788 3000 RESEARCH FORD 7902 3000 RESEARCH ADAMS 7876 1100 RESEARCH TURNER 7844 1500 SALES ALLEN 7499 1600 SALES JAMES 7900 950 SALES WARD 7521 1250 SALES MARTIN 7654 1250 SALES BLAKE 7698 2850 SALES 已选择15行。
[不等值连接]显示员工信息,员工号,姓名,月薪,薪水级别
SQL> select e.empno,e.ename,e.sal,s.grade from emp e,salgrade s where e.sal>=s.losal and e.sal<=hisal; 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 7902 FORD 3000 4 7788 SCOTT 3000 4 7839 KING 5000 5 1 tom_abc 8000 5 已选择15行。
多表查询4,求每个部门的人数:(需要分组)
) SQL> select *from dept; DEPTNO DNAME LOC ---------- ---------------------------- ---------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> 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 4 20 RESEARCH 5 30 SALES 6
[少了一个部门,这个方法有漏洞,因为40号部门没有员工]
[外连接]技术引出:
右外连接,+在等号的左边
SQL> 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 4 20 RESEARCH 5 30 SALES 6 =============================================== 左外连接,+在等号的右边 SQL> 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 4 40 OPERATIONS 0 20 RESEARCH 5 30 SALES 6
[难点]:[自连接]
显示老板的信息:
SQL> select *from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- -------------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-12月-80 800 20 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 1 tom_abc 8000 10 [这是对的] SQL> select e.ename 员工,b.ename 老板 from emp e,emp b where e.mgr=b.empno; 员工 老板 -------------------- -------------------- FORD JONES SCOTT JONES TURNER BLAKE ALLEN BLAKE WARD BLAKE JAMES BLAKE MARTIN BLAKE MILLER CLARK ADAMS SCOTT BLAKE KING JONES KING CLARK KING SMITH FORD 已选择13行。 [这是错误的] SQL> select a.ename 员工,b.ename 老板 from emp a,emp b where a.empno=b.mgr; 员工 老板 -------------------- -------------------- JONES FORD JONES SCOTT BLAKE TURNER BLAKE ALLEN BLAKE WARD BLAKE JAMES BLAKE MARTIN CLARK MILLER SCOTT ADAMS KING BLAKE KING JONES KING CLARK FORD SMITH 已选择13行。
[优化显示]
SQL> select e.ename ||‘ 的老板是 ‘||b.ename from emp e,emp b where e.mgr=b.empno(+); E.ENAME||‘的老板是‘||B.ENAME -------------------------------------------------------------------- FORD 的老板是 JONES SCOTT 的老板是 JONES JAMES 的老板是 BLAKE TURNER 的老板是 BLAKE MARTIN 的老板是 BLAKE WARD 的老板是 BLAKE ALLEN 的老板是 BLAKE MILLER 的老板是 CLARK ADAMS 的老板是 SCOTT CLARK 的老板是 KING BLAKE 的老板是 KING JONES 的老板是 KING SMITH 的老板是 FORD tom_abc 的老板是 KING 的老板是
[再优化]
SQL> select e.ename ||‘ 的老板是 ‘|| nvl(b.ename,‘他自己‘) from emp e,emp b where e.mgr=b.empno(+); E.ENAME||‘的老板是‘||NVL(B.ENAME,‘他自己‘) -------------------------------------------------------------------- FORD 的老板是 JONES SCOTT 的老板是 JONES JAMES 的老板是 BLAKE TURNER 的老板是 BLAKE MARTIN 的老板是 BLAKE WARD 的老板是 BLAKE ALLEN 的老板是 BLAKE MILLER 的老板是 CLARK ADAMS 的老板是 SCOTT CLARK 的老板是 KING BLAKE 的老板是 KING JONES 的老板是 KING SMITH 的老板是 FORD tom_abc 的老板是 他自己 KING 的老板是 他自己
[难点]:
1,查询每个部门的人数
分析:需要使用分组
分析:需要外连接(把部门为空的部门也显示出来)
SQL> select d.deptno,d.dname,count(e.ename) from emp e, dept d where d.deptno=e.deptno(+) group by d.deptno, d.dname order by d.deptno; DEPTNO DNAME COUNT(E.ENAME) ---------- ---------------------------- -------------- 10 ACCOUNTING 4 20 RESEARCH 5 30 SALES 6 40 OPERATIONS 0
本文出自 “魂斗罗” 博客,谢绝转载!
以上是关于数据库编程2 Oracle 过滤 函数 分组 外连接 自连接的主要内容,如果未能解决你的问题,请参考以下文章