diff --git a/README.md b/README.md index 111c3fd..84afab8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,36 @@ # learn_oracle_notebook -Oracle 学习笔记 \ No newline at end of file +Oracle 学习笔记 + +## 查询 Select +> +> 查询语句 + +当涉及到数据库查询时,子查询和表关联是非常常见的操作。让我通过一些简单的例子,并对每个例子进行简要的讲解来帮助你完善笔记。 + +### 子查询 + +#### 关联子查询 + +```sql +SELECT * +FROM employees +WHERE department_id IN + (SELECT department_id + FROM departments + WHERE location_id = 1700); +``` + +这个例子演示了一个关联子查询。内部的子查询先根据条件从departments表中选择特定的部门ID,然后外部的主查询根据这些部门ID从employees表中检索相关的员工信息。这种方式可以帮助我们根据内部查询的结果来过滤外部查询的数据。 + +### 表关联 + +#### 左连接 + +```sql +SELECT customers.name, orders.order_date +FROM customers +LEFT JOIN orders ON customers.id = orders.customer_id; +``` + +这个例子演示了左连接,它返回了所有的顾客信息以及与之关联的订单信息。即使某些顾客没有订单,也会返回顾客的信息。这在需要显示所有主体数据的情况下非常有用。 diff --git a/course/01-practice.sql b/course/01-practice.sql new file mode 100644 index 0000000..add9e6c --- /dev/null +++ b/course/01-practice.sql @@ -0,0 +1,107 @@ +-- 查询名字中有 k +-- 并薪水大于 2000 的员工姓名、薪水、以及年收入(12*(薪水+奖金)) +SELECT + ENAME, + SAL, + COMM, + NVL(COMM, 0), + 12*(SAL+NVL(COMM, 0)) YEAR_SAL +FROM + EMP +WHERE + ENAME LIKE '%K%' + AND SAL > 2000; + +-- 查询那些部门的平均薪水大于2000 +SELECT + * +FROM + ( + SELECT + DEPTNO, + AVG(NVL(SAL, 0)) AVG_SAL + FROM + EMP + WHERE + DEPTNO IS NOT NULL + GROUP BY + DEPTNO + HAVING + AVG(NVL(SAL, 0)) > 2000 + ORDER BY + DEPTNO + ) A + JOIN DEPT D + ON A.DEPTNO=D.DEPTNO; + +-- 那些人的薪水超过 10 部门的最高薪水 +SELECT + ENAME 姓名, + SAL 薪水, + DEPTNO 部门 +FROM + EMP E +WHERE + E.SAL > ( + SELECT + MAX(SAL) + FROM + EMP + WHERE + EMP.DEPTNO=20 + ); + +-- 查询各个部门的最低薪水 +SELECT + DEPTNO 部门号, + LOW_SAL 最低薪水 +FROM + ( + SELECT + MIN(NVL(SAL, 0)) LOW_SAL + FROM + EMP + GROUP BY + DEPTNO + ) L + JOIN EMP E + ON L.LOW_SAL=E.SAL; + +SELECT + DEPTNO 部门号, + MIN(SAL) 最低薪水 +FROM + EMP +GROUP BY + DEPTNO); + +-- 查询各个部门的平均大于20部门的平均薪水 +SELECT + DEPTNO, + AVG(NVL(SAL, 0)) +FROM + EMP +WHERE + DEPTNO IS NOT NULL +GROUP BY + DEPTNO +HAVING + AVG(NVL(SAL, 0)) > ( + SELECT + AVG(NVL(SAL, 0)) + FROM + EMP + WHERE + DEPTNO=20 + ) + -- 查询员工姓名、薪水、部门号、和部门名称 + SELECT + E.ENAME 姓名, + E.SAL 薪水, + E.ENAME 部门号, + E.DEPTNO 部门名称 + FROM + EMP E, + DEPT D + WHERE + E.DEPTNO=D.DEPTNO; \ No newline at end of file diff --git a/course/02-practice.sql b/course/02-practice.sql new file mode 100644 index 0000000..b852f71 --- /dev/null +++ b/course/02-practice.sql @@ -0,0 +1,298 @@ +/* + 练习2 +*/ + +-- 创建数据表 +CREATE TABLE USER_SK ( + ID NUMBER(4), + PASSWORD CHAR(4), + NAME CHAR(20), + PHONE CHAR(20), + EMAIL VARCHAR(50) +); + +-- 为表添加数据 +INSERT INTO USER_SK VALUES( + 1001, + '1234', + 'liucs', + '13600000000', + 'LIUCS@SINA.COM' +); + +-- 查询数据 +SELECT + * +FROM + USER_SK; + +/* + 案例-1 +*/ +-- 删除表 +DROP TABLE DEPT_SK; + +CREATE TABLE DEPT_SK( + DEPTNO NUMBER(2), + DNAME CHAR(20), + LOCATION CHAR(20) +); + +INSERT INTO DEPT_SK VALUES( + 10, + 'developer', + 'beijing' +); + +INSERT INTO DEPT_SK VALUES( + 20, + 'account', + 'shanghai' +); + +INSERT INTO DEPT_SK VALUES( + 30, + 'sales', + 'guangzhou' +); + +INSERT INTO DEPT_SK VALUES( + 40, + 'operations', + 'tianjin' +); + +COMMIT; + +-- 查询创建的 DEPT_SK 表 +SELECT + * +FROM + DEPT_SK; + +/* + 案例-1 + 创建表: EMP + */ +-- 创建表 EMP_SK +CREATE TABLE EMP_SK( + EMPNO NUMBER(4), + ENAME VARCHAR2(20), + JOB VARCHAR2(15), + SALARY NUMBER(7, 2), + BONUS NUMBER(7, 2), + HIREDATE DATE, + MGR NUMBER(4), + DEPTNO NUMBER(10) +); + +-- 插入数据 +INSERT INTO EMP_SK VALUES( + 1001, + '张无忌', + 'Manager', + 10000, + 2000, + '', + 1005, + 10 +); + +INSERT INTO EMP_SK VALUES( + 1002, + '刘芒松', + 'Analyst', + 8000, + 1000, + '', + NULL, + 10 +); + +INSERT INTO EMP_SK VALUES( + 1003, + '李翔', + 'Analyst', + 9000, + 1000, + '', + 1001, + 10 +); + +INSERT INTO EMP_SK VALUES( + 1004, + '郭英莹', + 'Programmer', + 5000, + NULL, + '', + 1001, + 10 +); + +INSERT INTO EMP_SK VALUES( + 1005, + '张三丰', + 'President', + 15000, + NULL, + '', + NULL, + 20 +); + +INSERT INTO EMP_SK VALUES( + 1006, + '燕小六', + 'Manager', + 5000, + 400, + '', + 1005, + 20 +); + +INSERT INTO EMP_SK VALUES( + 1007, + '陆无双', + 'Clerk', + 3000, + 500, + '', + 1006, + 20 +); + +INSERT INTO EMP_SK VALUES( + 1008, + '黄莺', + 'Manager', + 5000, + 500, + '', + 1005, + 30 +); + +INSERT INTO EMP_SK VALUES( + 1009, + '乔小宝', + 'Salesman', + 4000, + NULL, + '', + 1008, + 30 +); + +INSERT INTO EMP_SK VALUES( + 1010, + '郭琦', + 'Salesman', + 4500, + 500, + '', + 1008, + 30 +); + +-- 设置显示格式 +set linesize 150; + +col empno for 9999; + +col mgr for 9999; + +col deptno for 99; + +col salary for 99999.99; + +-- 查询表 +SELECT + * +FROM + EMP_SK; + +-- 插入一条ID 为1011, 姓名为 '余泽成', 其余字段为NULL 的数据 +INSERT INTO EMP_SK( + EMPNO, + ENAME +) VALUES( + 1011, + '余泽成' +); + +-- 查询EMP_XXX 表, 如果没有职位, 显示'no position', 如果有职位, 显示员工的职位 +SELECT + ENAME, + NVL(JOB, '无职位') +FROM + EMP_SK; + +/* + 案例2-关联子查询 + */ + +-- 哪些员工的薪水比公司的平均薪水低? +SELECT + ENAME, + SALARY +FROM + EMP_SK +WHERE + SALARY < ( + SELECT + AVG(NVL(SALARY, 0)) + FROM + EMP_SK + ); + +-- 哪些员工的薪水比本部门的平均薪水低?不再和整个部门的平均薪水比较。 +SELECT + E.ENAME, + E.SALARY, + E.DEPTNO +FROM + EMP_SK E + JOIN ( + SELECT + AVG(NVL(SALARY, 0)) NEW_SALARY, + DEPTNO + FROM + EMP_SK + WHERE + SALARY IS NOT NULL + GROUP BY + DEPTNO + ) NE + ON E.DEPTNO=NE.DEPTNO +WHERE + E.SALARY < NE.NEW_SALARY +ORDER BY + DEPTNO; + +-- 只查询当前时间 +SELECT + SYSDATE +FROM + DUAL; + +/* + 案例3-关联子查询 + */ +-- 哪些人是其他人的经理?( 查找有下属的员工 ) +SELECT + ENAME, + EMPNO +FROM + EMP_SK E +WHERE + EXISTS ( + SELECT + 1 + FROM + EMP_SK + WHERE + MGR=E.EMPNO + ); \ No newline at end of file diff --git a/course/03-practice.sql b/course/03-practice.sql new file mode 100644 index 0000000..7d8a90a --- /dev/null +++ b/course/03-practice.sql @@ -0,0 +1,135 @@ +/* + Author: Fromsko + DATE: 2024.09.10 20:30 +*/ + +-- 查询两个表 +SELECT + * +FROM + EMP_WHC; + +SELECT + * +FROM + DEPT_WHC; + +-- 工资大于张无忌的 +SELECT + ENAME, + SALARY +FROM + EMP_WHC +WHERE + SALARY > ANY( + SELECT + SALARY + FROM + EMP_WHC + WHERE + ENAME='张无忌' + ); + +SELECT + ENAME, + DEPTNO +FROM + EMP_WHC +WHERE + DEPTNO IN ( + SELECT + DEPTNO + FROM + EMP_WHC + WHERE + ENAME='张无忌' + ) + AND ENAME<>'张无忌'; + +SELECT + ENAME, + E.DEPTNO, + A.COU, + A.AVG_SAL +FROM + EMP_WHC E, + ( + SELECT + DEPTNO, + COUNT(*) COU, + AVG(NVL(SALARY, 0)) AVG_SAL + FROM + EMP_WHC + WHERE + DEPTNO IS NOT NULL + GROUP BY + DEPTNO + ) A +WHERE + E.DEPTNO = A.DEPTNO; + +-- +SELECT + DEPTNO, + AVG(NVL(SALARY, 0)) +FROM + EMP_WHC +WHERE + DEPTNO IS NOT NULL +GROUP BY + DEPTNO +HAVING + AVG(NVL(SALARY, 0)) > ( + SELECT + AVG(NVL(SALARY, 0)) + FROM + EMP_WHC + WHERE + DEPTNO=20 + ); + +--列出员工的名字薪水和部门还有职位 要求这些员工所在 +--部门的人数比10部门的人数多 +SELECT + ENAME, + SALARY, + DEPTNO, + JOB +FROM + EMP_WHC +WHERE + DEPTNO IN ( + SELECT + DEPTNO + FROM + EMP_WHC + WHERE + DEPTNO IS NOT NULL + GROUP BY + DEPTNO + HAVING + COUNT(*) > ( + SELECT + COUNT(*) + FROM + EMP_WHC + WHERE + DEPTNO =10 + ) + ); + +--那些员工的薪水比本部门的平均薪水低? +SELECT + ENAME, + SALARY +FROM + EMP_WHC E +WHERE + SALARY <( + SELECT + AVG(SALARY) + FROM + EMP_WHC + WHERE + DEPTNO = E.DEPTNO + ) \ No newline at end of file diff --git a/course/03-test.sql b/course/03-test.sql new file mode 100644 index 0000000..1a800db --- /dev/null +++ b/course/03-test.sql @@ -0,0 +1,92 @@ +/* + Author: Fromsko + DATE: 2024.09.10 20:30 +*/ + +-- 更新赵敏的数据 +UPDATE EMP_WHC +SET + MGR = 1002 +WHERE + ENAME = '赵敏'; + +-- 总数居 +SELECT + * +FROM + EMP_WHC; + +-- 谁是张无忌的下属? (MGR=EMPNO=1002) +SELECT + ENAME +FROM + EMP_WHC +WHERE + MGR IN ( + SELECT + EMPNO + FROM + EMP_WHC + WHERE + ENAME='张无忌' + ); + +-- + +/* + 子查询: + 子查询的条件是单列还是多列没关系, + 关键是要分清返回的是单行还是多行 + + - 如果是单行, 用单行比较运算符, =, >, < 这些 + - 如果是多行, 用IN, >ALL, >ANY,