此书及其相关脚本下载方法:关注微信公众号,点击功能介绍-书籍链接下载,即可获取
SQLCOOK教程笔记
1.检索记录
--1.1从表中检索所有行列
SELECT * FROM hyz_emp;
--1.2从表中检索部分行
SELECT * FROM hyz_emp s WHERE s.deptno = 10;
--1.3查找满足多个条件的行
SELECT *
FROM hyz_emp s
WHERE s.deptno = 10 --deptno=10
OR s.comm IS NOT NULL --或comm不是NULL
OR s.sal <= 2000 --或sal小于2000
AND s.deptno = 20 --并且deptno=20
;
/*1.3.1等同于*/
SELECT *
FROM hyz_emp s
WHERE (s.deptno = 10 --deptno=10或comm不是NULL
OR s.comm IS NOT NULL)
OR (s.sal <= 2000 --或sal小于2000并且deptno=20
AND s.deptno = 20);
/*1.3.2等同于*/
SELECT *
FROM hyz_emp s
WHERE (s.deptno = 10 --deptno=10或comm不是NULL
OR s.comm IS NOT NULL)
UNION
SELECT *
FROM hyz_emp s
WHERE (s.sal <= 2000 --sal小于2000并且deptno=20
AND s.deptno = 20);
/*1.3.3如果用此括号方式,含义就不一样了*/
SELECT *
FROM hyz_emp s
WHERE (s.deptno = 10 --deptno=20中存在deptno=10或comm不是NULL或sal小于2000
OR s.comm IS NOT NULL OR s.sal <= 2000)
AND s.deptno = 20;
/*1.3.4查看deptno = 20结果,很明显不能满足deptno=10,也不能满足comm不是NULL,
但是满足了sal小于2000存在两条,所以得出1.3.3代码中最终显示结果*/
SELECT * FROM hyz_emp s WHERE s.deptno = 20;
--1.4从表中检索部分列
SELECT s.ename, s.deptno, s.sal FROM hyz_emp s; --这样可以不用返回多余字段,也可以节约时间
--1.5为列取有意义的名称
SELECT s.sal AS 工资, s.comm AS 奖金 FROM hyz_emp s;
--1.6在WHERE子句中引用取别名的列
SELECT *
FROM (SELECT s.sal AS 工资, s.comm AS 奖金 FROM hyz_emp s) k
WHERE k.奖金 IS NOT NULL
AND k.工资 = 1250;
--1.7连接列值s
SELECT s.ename || '的工作是' || decode(s.mgr,
NULL,
'董事长',
decode(s.job,
'会计',
'员工',
'研究员',
'员工',
'销售员',
'员工',
'操作员',
'员工')) AS ename_job,
s.mgr
FROM hyz_emp s;
--1.8在select语句中使用条件逻辑
SELECT s.ename,
s.sal,
(CASE
WHEN s.sal <= 2000 THEN
'所得报酬过低'
WHEN s.sal >= 4000 THEN
'所得报酬过高'
ELSE
'一般'
END) AS status --状态
FROM hyz_emp s;
--1.9限制返回的行数
SELECT * FROM hyz_emp s WHERE rownum <= 5;
--1.10从表中随机返回n条记录
SELECT ename, job
FROM (SELECT s.ename, s.job FROM hyz_emp s ORDER BY dbms_random.value()) k
WHERE rownum <= 5;
--1.11查找空值
SELECT *
FROM hyz_emp s
WHERE s.comm IS NULL
AND s.mgr IS NOT NULL;
--1.12将空值转换为实际值
SELECT coalesce(s.comm, 0) AS comm FROM hyz_emp s; --从左往右数,遇到第一个非null值,则返回该非null值。
/*等同于
*/
SELECT nvl(s.comm, 0) AS comm FROM hyz_emp s; --如果第一个参数为null,则返回第二个参数,反之返回第一个参数
/*第一点区别:nvl只适合于两个参数的,COALESCE适合于多个参数。
第二点区别:COALESCE里的所有参数类型必须保持一致,nvl可以不一致。*/
--1.13按模式搜索
SELECT s.ename, s.job FROM hyz_emp s WHERE s.deptno IN (10, 20);
SELECT s.ename, s.job
FROM hyz_emp s
WHERE s.deptno IN (10, 20)
AND (s.ename LIKE '%俊明%' OR s.ename LIKE '%乾');
2.查询结果排序
--2.1以指定的次序返回查询结果
SELECT s.ename, s.job, s.sal
FROM hyz_emp s
WHERE s.deptno = 10
ORDER BY s.sal ASC; --升序
SELECT s.ename, s.job, s.sal
FROM hyz_emp s
WHERE s.deptno = 10
ORDER BY s.sal DESC; --降序
SELECT s.ename, s.job, s.sal
FROM hyz_emp s
WHERE s.deptno = 10
ORDER BY 3 ASC; --可以使用数字,但是不推荐
--2.2按多个字段排序
SELECT s.ename, s.deptno, s.job, s.sal
FROM hyz_emp s
WHERE s.deptno = 10
ORDER BY s.deptno, s.sal DESC;
--2.3按子串排序
SELECT s.ename, s.job
FROM hyz_emp s
ORDER BY substr(s.job, length(s.job) - 2);
--2.4对字母数字混合的数据排序
SELECT s.ename || ' ' || s.deptno AS data FROM hyz_emp s;
/*order by hyz_deptno*/
SELECT s.ename || ' ' || s.deptno AS data
FROM hyz_emp s
ORDER BY REPLACE(data,
REPLACE(translate(data, '0123456789', '#########'),
'#',
''),
'');
SELECT s.ename || ' ' || s.deptno AS data
FROM hyz_emp s
ORDER BY regexp_substr(data, '[0-9]+') ASC;
/*order by ename*/
SELECT s.ename || ' ' || s.deptno AS data
FROM hyz_emp s
ORDER BY REPLACE(translate(data, '0123456789', '#########'), '#', '');
SELECT s.ename || ' ' || s.deptno AS data
FROM hyz_emp s
ORDER BY regexp_substr(data, '[[:alnum:]]+') ASC;
--2.5处理排序空值
SELECT s.ename,
s.sal,
s.comm,
(CASE
WHEN s.comm IS NULL THEN
0
ELSE
1
END) AS is_null
FROM hyz_emp s;
--2.6根据数据项的键排序
SELECT s.ename,
s.sal,
s.comm,
(CASE
WHEN s.comm IS NULL THEN
s.sal
ELSE
s.comm
END) AS ordered,
s.*
FROM hyz_emp s
ORDER BY ordered;
3.操作多个表
--3.1记录集的叠加
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s
WHERE s.deptno = 10
UNION ALL --并集,不去除重复
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s;
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s
WHERE s.deptno = 10
UNION --并集,去除重复
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s;
SELECT s.ename, s.sal, s.comm, s.deptno FROM hyz_emp s;
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s
WHERE s.deptno = 10
INTERSECT --交集
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s;
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s
WHERE s.deptno = 10
MINUS --差集
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s;
--3.2组合相关的行
SELECT e.ename, d.loc, e.*, d.*
FROM hyz_emp e, hyz_dept d
WHERE e.deptno = d.deptno --防止笛卡儿积
AND e.deptno = 10;
/*等同于*/
SELECT e.ename, d.loc, e.*, d.*
FROM hyz_emp e
JOIN hyz_dept d
ON e.deptno = d.deptno --防止笛卡儿积
AND e.deptno = 10;
--3.3在两个表中查找共同行
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s
WHERE s.deptno = 10
INTERSECT --交集
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s;
/*等同于*/
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s
JOIN hyz_emp o
ON s.empno = o.empno
AND s.ename = o.ename
AND s.job = o.job
WHERE s.deptno = 10;
--3.4从一个表中查找另一个表没有的值
CREATE OR REPLACE view sqlcook_emp_3_4 AS
SELECT s.ename, s.sal, s.comm, s.deptno + 1 AS deptno
FROM hyz_emp s
WHERE s.deptno = 10;
SELECT s.ename, s.sal, s.comm, s.deptno AS deptno
FROM sqlcook_emp_3_4 s
WHERE s.deptno = 11
MINUS --差集
SELECT s.ename, s.sal, s.comm, s.deptno
FROM hyz_emp s;
/*等同于*/
SELECT s.ename, s.sal, s.comm, s.deptno AS deptno
FROM sqlcook_emp_3_4 s
WHERE s.deptno = 11
AND NOT EXISTS
(SELECT t.deptno FROM hyz_emp t WHERE s.deptno = t.deptno);
--3.5在一个表中查找与其他表不匹配的记录
SELECT * FROM hyz_emp;
SELECT *
FROM hyz_dept d
JOIN hyz_emp e
ON d.deptno = e.deptno(+)
AND e.deptno IS NULL;
--3.6向查询中增加联接而不影响其他联接
SELECT e.*, d.* FROM hyz_dept d LEFT JOIN hyz_emp e ON e.deptno = d.deptno;
--3.7检测两个表中是否有相同的数据
CREATE OR REPLACE view sqlcook_emp_3_6 AS
SELECT *
FROM hyz_emp s
WHERE s.deptno != 10
UNION ALL
SELECT *
FROM hyz_emp s
WHERE s.ename = '乐正开济';
(
SELECT s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno,
COUNT(*) AS n
FROM hyz_emp s
GROUP BY s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno
MINUS
SELECT s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno,
COUNT(*) AS n
FROM sqlcook_emp_3_6 s
GROUP BY s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno)
UNION (SELECT s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno,
COUNT(*) AS n
FROM sqlcook_emp_3_6 s
GROUP BY s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno
MINUS
SELECT s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno,
COUNT(*) AS n
FROM hyz_emp s
GROUP BY s.empno,
s.ename,
s.job,
s.mgr,
s.hiredate,
s.sal,
s.comm,
s.deptno);
--3.8识别和消除笛卡儿积
SELECT e.ename, d.loc
FROM hyz_emp e
JOIN hyz_dept d
ON e.deptno = d.deptno
AND e.deptno = 10;
--3.9聚集和联接
CREATE OR REPLACE view sqlcook_emp_3_9 AS
SELECT s.empno,
s.hiredate AS received,
(CASE
WHEN s.sal <= 800 THEN
1
WHEN s.sal BETWEEN 801 AND 1999 THEN
2
WHEN s.sal BETWEEN 2000 AND 5000 THEN
3
ELSE
4
END) AS TYPE
FROM hyz_emp s;
SELECT DISTINCT deptno, total_sal, total_bonus
FROM (SELECT e.empno,
e.ename,
SUM(DISTINCT e.sal) over(PARTITION BY deptno) AS total_sal,
e.deptno,
SUM(e.sal * (CASE
WHEN eb.type = 1 THEN
0.1
WHEN eb.type = 2 THEN
0.2
WHEN eb.type = 3 THEN
0.3
ELSE
0.4
END)) over(PARTITION BY deptno) AS total_bonus
FROM hyz_emp e
JOIN sqlcook_emp_3_9 eb
ON e.empno = eb.empno
AND e.deptno = 10) x; --1614898
SELECT SUM(DISTINCT s.sal) AS total_sal FROM hyz_emp s WHERE s.deptno = 10; --1614898
--3.10聚集和外联接
SELECT DISTINCT deptno, total_sal, total_bonus
FROM (SELECT e.empno,
e.ename,
SUM(DISTINCT e.sal) over(PARTITION BY deptno) AS total_sal,
e.deptno,
SUM(e.sal * (CASE
WHEN eb.type = 1 THEN
0.1
WHEN eb.type = 2 THEN
0.2
WHEN eb.type = 3 THEN
0.3
ELSE
0.4
END)) over(PARTITION BY deptno) AS total_bonus
FROM hyz_emp e
JOIN sqlcook_emp_3_9 eb
ON e.empno = eb.empno(+)
AND e.deptno = 10) x; --1614898
--3.11从多个表中返回丢失的数据
SELECT d.deptno, d.dname, e.ename, e.deptno
FROM hyz_dept d
JOIN hyz_emp e
ON d.deptno = e.deptno(+)
AND e.deptno IS NULL
UNION
SELECT d.deptno, d.dname, e.ename, e.deptno
FROM hyz_dept d
JOIN hyz_emp e
ON d.deptno(+) = e.deptno
AND e.deptno IS NULL;
--3.12在运算和比较时使用NULL值
SELECT s.ename, s.comm, coalesce(s.comm, 0) AS comm
FROM hyz_emp s
WHERE coalesce(s.comm, 0) <
(SELECT comm FROM hyz_emp WHERE ename = '雷立诚');
4.插入,更新与删除
--4.1插入新记录
INSERT INTO hyz_dept
(deptno, total_sal, total_bonus)
VALUES
(60, '业务员', '江苏');
COMMIT;
--4.2插入默认值
INSERT INTO hyz_emp (empno, comm) VALUES (0, DEFAULT);
ROLLBACK;
--4.3用NULL值代替默认值
INSERT INTO hyz_emp (empno, comm) VALUES (0, NULL);
ROLLBACK;
--4.4从一个表中从另一个表中复制行
INSERT INTO hyz_dept
(deptno, dname, loc)
SELECT s.deptno + 40, s.dname, s.loc
FROM hyz_dept s
WHERE s.loc IN ('深圳', '广州');
ROLLBACK;
--4.5复制表定义
CREATE TABLE bonus AS
SELECT * FROM hyz_bonus s WHERE 0 = 1;
SELECT * FROM bonus;
drop TABLE bonus;
--4.6一次向多个表中插入记录
CREATE TABLE dept_east AS --东
SELECT * FROM hyz_dept s WHERE 0 = 1;
CREATE TABLE dept_north AS --北
SELECT * FROM hyz_dept s WHERE 0 = 1;
CREATE TABLE dept_south AS --南
SELECT * FROM hyz_dept s WHERE 0 = 1;
CREATE TABLE dept_west AS --西
SELECT * FROM hyz_dept s WHERE 0 = 1;
INSERT ALL WHEN loc IN
('上海', '江苏') THEN INTO dept_east
(deptno, dname, loc)
VALUES
(deptno, dname, loc) WHEN loc = '北京' THEN INTO dept_north
(deptno, dname, loc)
VALUES
(deptno, dname, loc) WHEN loc IN
('湖南', '深圳', '广州') THEN INTO dept_south
(deptno, dname, loc)
VALUES
(deptno, dname, loc) ELSE INTO dept_west
(deptno, dname, loc)
VALUES
(deptno, dname, loc)
SELECT deptno, dname, loc FROM hyz_dept;
COMMIT;
SELECT * FROM dept_east; --东
SELECT * FROM dept_south; --南
SELECT * FROM dept_west; --西
SELECT * FROM dept_north; --北
drop TABLE dept_east; --东
drop TABLE dept_south; --南
drop TABLE dept_west; --西
drop TABLE dept_north; --北
--4.7阻止对某几列插入
/*创建视图,视图的插入只适用于简单的视图,它实际上会转换插入到原表*/
CREATE OR REPLACE view sqlcook_emp_4_7 AS
SELECT empno, ename, job FROM hyz_emp;
SELECT * FROM sqlcook_emp_4_7;
INSERT INTO sqlcook_emp_4_7
(empno, ename, job)
VALUES
(0, '二次猿', '会计');
ROLLBACK;
--4.8在表中编辑记录
SELECT * FROM hyz_emp;
UPDATE hyz_emp s SET s.sal = s.sal * 1.1 WHERE s.deptno = 10;
ROLLBACK;
--4.9当对应行存在时更新
SELECT * FROM hyz_emp;
SELECT * FROM hyz_bonus;
UPDATE hyz_emp
SET sal = sal * 1.3
WHERE EXISTS (SELECT s.job FROM hyz_bonus s WHERE s.job = job);
ROLLBACK;
--4.10用其他的表中的值更新
SELECT s.empno, s.ename, s.job, s.mgr, s.hiredate, s.sal, s.comm, s.deptno
FROM hyz_emp s;
SELECT s.deptno, s.dname, s.loc FROM hyz_dept s;
UPDATE (SELECT s.empno,
s.ename,
s.deptno AS emp_deptno,
o.deptno AS deptno,
s.job AS job,
o.dname AS dname,
o.loc AS loc
FROM hyz_emp s
JOIN hyz_dept o
ON s.deptno = o.deptno)
SET emp_deptno = deptno, job = dname;
ROLLBACK;
--4.11合并记录
CREATE TABLE sqlcook_emp_4_11 AS
SELECT s.deptno, s.empno, s.ename, s.comm
FROM hyz_emp s
WHERE s.deptno = 10;
SELECT s.deptno, s.empno, s.ename, s.comm FROM sqlcook_emp_4_11 s;
MERGE INTO sqlcook_emp_4_11 ec
USING (SELECT * FROM hyz_emp) emp
ON (ec.empno = emp.empno)
WHEN MATCHED THEN
UPDATE SET ec.comm = 1000 DELETE WHERE (emp.sal < 2000)
WHEN NOT MATCHED THEN
INSERT
(ec.empno, ec.ename, ec.deptno, ec.comm)
VALUES
(emp.empno, emp.ename, emp.deptno, emp.comm);
COMMIT;
SELECT s.deptno, s.empno, s.ename, s.comm FROM hyz_emp s;
--4.12从表中删除所有记录
DELETE FROM hyz_emp;
ROLLBACK;
--4.13从表中删除指定记录
DELETE FROM hyz_emp s WHERE s.deptno = 10;
ROLLBACK;
--4.14删除单个记录
DELETE FROM hyz_emp s WHERE s.empno = 2017;
ROLLBACK;
--4.15删除违反参照完整性的记录
DELETE hyz_emp s
WHERE EXISTS (SELECT o.deptno FROM hyz_dept o WHERE s.deptno = o.deptno);
ROLLBACK;
--4.16删除重复记录
SELECT s.empno, s.job FROM hyz_emp s;
SELECT MIN(s.empno), s.job FROM hyz_emp s GROUP BY s.job;
DELETE hyz_emp s
WHERE s.empno NOT IN (SELECT MIN(s.empno) FROM hyz_emp s GROUP BY s.job);
ROLLBACK;
--4.17删除从其他表引用的记录
DELETE hyz_emp s
WHERE s.deptno IN (SELECT o.deptno
FROM hyz_dept o
HAVING COUNT(*) = 1
GROUP BY o.deptno);
ROLLBACK;
5.元数据查询
--5.1列出模式中的表
SELECT s.table_name FROM all_tables s WHERE s.owner = 'HUYINGZHAO';
--5.2列出表中的列
SELECT s.column_name, s.data_type, s.column_id
FROM all_tab_columns s
WHERE s.owner = 'HUYINGZHAO'
AND s.table_name = 'HYZ_EMP';
--5.3列出表中的索引列
SELECT s.table_name, s.index_name, s.column_name, s.column_position
FROM all_ind_columns s
WHERE s.table_name = 'HYZ_EMP'
AND s.table_owner = 'HUYINGZHAO';
--5.4列出表中的约束
SELECT a.table_name, a.constraint_name, b.column_name, a.constraint_type
FROM all_constraints a
JOIN all_cons_columns b
ON a.owner = b.owner
AND a.table_name = b.table_name
AND a.constraint_name = b.constraint_name
WHERE a.table_name = 'HYZ_EMP'
AND a.owner = 'HUYINGZHAO';
--5.5列出没有相应索引的外键
SELECT a.table_name,
a.constraint_name,
a.column_name,
c.index_owner,
c.index_name
FROM all_cons_columns a, all_constraints b, all_ind_columns c
WHERE a.owner = b.owner
AND a.table_name = b.table_name
AND a.constraint_name = b.constraint_name
AND a.owner = c.table_owner(+)
AND a.table_name = c.table_name(+)
AND a.column_name = c.column_name(+)
AND c.index_owner IS NULL
AND a.owner = 'HUYINGZHAO'
AND a.table_name = 'HYZ_EMP'
AND b.constraint_type = 'R';
--5.6使用SQL来生成SQL
SELECT 'select count(*) from ' || s.table_name || ';' FROM user_tables s;
--5.7在ORACLE中描述数据字典视图
SELECT s.column_name, s.comments
FROM dict_columns s
WHERE s.table_name = 'ALL_TAB_COLUMNS';
6.使用字符串
SELECT 'g''day mate' q FROM dual;
SELECT 'beavers'' teeth' FROM dual;
SELECT '''' FROM dual;
SELECT q'{hell'o}' AS q FROM dual;
SELECT q'[hell'o]' AS q FROM dual;
SELECT q'(hell'o)' AS q FROM dual;
--6.3计算字符在字符串出现的次数
SELECT (length('HELLO HELLO') - length(REPLACE('HELLO HELLO', 'LL', ''))) /
length('LL') AS h
FROM dual;
--6.4从字符串中删除不需要的字符
--'a'起到占位符.无实际意义
SELECT ename,
REPLACE(translate(ename, 'AEIOU', 'a'), 'a') AS stripped1,
sal,
REPLACE(sal, 0, '') AS stripped2
FROM scott.emp;
SELECT REPLACE(translate('EAECOUUUU', 'AEIOU', 'a'), 'a') AS stripped1
FROM dual;
--第六章后面几乎可以用正则表达式代替,可以略过
7.使用数字
--7.1计算平均值
SELECT AVG(s.mgr) FROM scott.emp s;
--7.2求某列的最大值/最小值
SELECT MAX(s.sal), MIN(s.mgr) FROM scott.emp s;
--7.3对某列的值求和
SELECT SUM(sal) FROM hyz_emp;
--7.4求一个表的行数
SELECT COUNT(*) FROM hyz_emp; --如果此列所有字段都为NULL,会忽略为NULL的列,9999
--7.5求某列值的个数
SELECT COUNT(s.comm) FROM hyz_emp s; --如果指定字段的值为NULL,会忽略为NULL的列,9975
--7.6生成累计和
SELECT empno,
sal,
SUM(sal) over(ORDER BY sal, empno) AS running_totdal1,
SUM(sal) over(ORDER BY sal) AS running_totdal2
FROM hyz_emp
ORDER BY 2;
--7.7生成累乘积
--此函数为0和负数无法正常输出
SELECT s.empno,
s.ename,
s.sal,
exp(SUM(ln(s.sal)) over(ORDER BY s.sal, s.empno)) AS running_prod
FROM hyz_emp s
WHERE s.deptno = 10;
--可包含0和负数的,只取负数
SELECT empno, ename, sal, tmp AS running_prod
FROM (SELECT empno, ename, -sal AS sal FROM hyz_emp WHERE deptno = 10) model dimension BY(row_number() over(ORDER BY sal DESC) rn) measures(sal, 0 tmp, empno, ename) rules(tmp [ ANY ] = (CASE
WHEN sal [
cv() - 1
] IS NULL THEN
sal [ cv() ]
ELSE
tmp [
cv() - 1
] * sal [ cv() ]
END));
--7.8计算累计差
SELECT ename,
sal,
SUM((CASE
WHEN rn = 1 THEN
sal
ELSE
-sal
END)) over(ORDER BY sal, empno) AS running_diff
FROM (SELECT empno,
ename,
sal,
row_number() over(ORDER BY sal, empno) AS rn
FROM hyz_emp
WHERE deptno = 10) x;
--7.9计算模式
--出现最频繁的数据
SELECT MAX(sal) keep(dense_rank FIRST ORDER BY cnt DESC) sal
FROM (SELECT sal, COUNT(1) cnt FROM hyz_emp WHERE deptno = 10 GROUP BY sal);
--7.10计算中间值
SELECT median(sal) FROM hyz_emp WHERE deptno = 20;
SELECT percentile_cont(0.5) within GROUP(ORDER BY sal)
FROM hyz_emp
WHERE deptno = 20;
SELECT sal FROM hyz_emp WHERE deptno = 20 ORDER BY sal;
--5 6258.00
--6 6628.00
SELECT (6258.00 + 6628.00) / 2 FROM dual;
--7.11求总和的百分比
SELECT (d10 / total) * 100 AS pct
FROM (SELECT DISTINCT deptno,
SUM(sal) over() total,
SUM(sal) over(PARTITION BY deptno) d10
FROM hyz_emp) x
WHERE deptno = 10; --33.0741744459662
SELECT SUM(sal) total FROM hyz_emp s WHERE s.deptno = 10; --3332020
SELECT SUM(sal) total FROM hyz_emp s WHERE s.deptno = 20;
SELECT SUM(sal) total FROM hyz_emp s WHERE s.deptno = 30;
SELECT SUM(sal) total FROM hyz_emp s WHERE s.deptno = 40;
SELECT SUM(sal) total FROM hyz_emp s; --10074386
SELECT 3332020 / 10074386 * 100 FROM dual; --33.0741744459662
--7.12对可空列作聚集
--coalesce和nvl会忽略NULL值不计数
SELECT AVG(coalesce(comm, 0)) AS avg_comm FROM hyz_emp WHERE deptno = 30;--246.949579831933
SELECT AVG(nvl(comm, 0)) AS avg_comm FROM hyz_emp WHERE deptno = 30;--246.949579831933
SELECT AVG(comm) AS avg_comm FROM hyz_emp WHERE deptno = 30;--247.767539897621
--7.13计算不包含最大值和最小值的均值
SELECT AVG(sal)
FROM (SELECT sal, MIN(sal) over() AS min_sal, MAX(sal) over() AS max_sal
FROM hyz_emp) x
WHERE sal NOT IN (min_sal, max_sal);
--7.14把数字字母串转为数值
SELECT regexp_substr('paull12332g14h334', '[0-9]+') AS s FROM dual;
本人是一枚程序猿,如果觉得整理的不错,请关注个人微信公众号(扫一扫):