原义字符串 ( LiteralCharacter Strings) 原义字符指字符、数字,或者日期。 日期和字符需要使用单引号封装。 每行数据显示一次。 … SELECT last_name ||' is a '||job_id AS "Employee Details" FROM employees;
使用比较运算符 SELECT last_name,salary FROM employees WHERE salary BETWEEN 2500 AND 3500 ; 使用 BETWEEN 操作显示符合范围的值 : 下限 上限
22.
使用比较运算符 SELECT employee_id,last_name, salary, manager_id FROM employees WHERE manager_id IN (100, 101, 201) ; 使用 IN 操作符 显示符合列表内值的数据 :
23.
使用比较运算符 LIKE 操作符筛先符合查找字符串的数据行。 查找条件可以包括字符或数字: “ %” 表示数字 0 或者多个字符。 “ _” 表示一个字符。 SELECT first_name FROM employees WHERE first_name LIKE 'S%' ;
24.
使用比较运算符 可以同时使用 (%, _) 匹配符 : 使用 ESCAPE “\” 标识符查找值中含有“ %” 和 “ _” 字符的数据。 SELECT last_name FROM employees WHERE last_name LIKE '_o%' ; SELECT last_name FROM employees WHERE last_name LIKE '%SA\_%' ESCAPE '\';
25.
使用比较运算符 SELECT last_name,manager_id FROM employees WHERE manager_id IS NULL ; 使用 IS NULL 操作检验是否有 Null 值
26.
逻辑运算符 如果条件为假,则返回 TRUENOT 如果前后两个条件有一个为真,则返回 TRUE OR 如果前后两个条件都为真,则返回 TRUE AND Meaning Operator
27.
使用逻辑运算符 SELECT employee_id,last_name, job_id, salary FROM employees WHERE salary >= 10000 AND job_id LIKE '%MAN%' ; AND 需要前后两个条件为 TRUE:
28.
使用逻辑运算符 OR 需要前后两个条件有一个为 TRUE: SELECT employee_id, last_name, job_id, salary FROM employees WHERE salary >= 10000 OR job_id LIKE '%MAN%' ;
29.
使用逻辑运算符 NOT 操作符可以与 IN, BETWEEN, LIKE, and NULL 配合使用 : ... WHERE job_id NOT IN ('AC_ACCOUNT', 'AD_VP') ... WHERE salary NOT BETWEEN 10000 AND 15000 ... WHERE last_name NOT LIKE '%A%‘ ... WHERE commission_pct IS NOT NULL
30.
运算符的优先级规则 可以使用括号改变默认的优先级别 Notequal to 6 NOT 7 AND 8 OR 9 IS [NOT] NULL , LIKE , [NOT] IN 4 [NOT] BETWEEN 5 比较运算符 3 连接运算符 2 四则运算 1 运算符 优先级
31.
排序 ORDER BY排序使用 ORDER BY 子句 : ASC: 升序 ( 默认行为 ) DESC: 倒序 如果不使用 ORDER BY ,相同的两次查询返回的结果顺序可以不一样。 使用 NULL FIRST 和 NULL LAST 指定 NULL 值在排序中的位置。 ORDER BY 子句中的每个列都可以单独指定排序顺序。
替换变量 Substitution Variables替换变量临时保存数据,使用“ &” 和“ &&” 符号 替换变量可用于: WHERE 条件子句 ORDER BY 子句 列表达式 表名 整个 SELECT 语句 SELECT employee_id, last_name, job_id, &&column_name FROM employees ORDER BY &column_name ;
数据类型的隐式转换 NUMBER VARCHAR2or CHAR DATE VARCHAR2 or CHAR To From VARCHAR2 or CHAR NUMBER VARCHAR2 or CHAR DATE To From … where hire_date > '01-JAN-90' … where name_varchar > 2345 不建议使用隐式转换,可能导致 SQL 的性能下降
条件表达式 Conditional ExpressionsIF-THEN-ELSE 的逻辑判断 有两种方法: CASE DECODE CASE expr WHEN comparison_expr1 THEN return_expr1 [WHEN comparison_expr2 THEN return_expr2 WHEN comparison_exprn THEN return_exprn ELSE else_expr ] END DECODE( col|expression, search1, result1 [ , search2, result2,..., ] [ , default ])
数据分组 GROUPBY 表 EMPLOYEES … 在 EMPLOYEES 表中,计算每个部门的平均工资 SELECT column , group_function(column) FROM table [WHERE condition ] [GROUP BY group_by_expression ] [ORDER BY column ]; 4400 9500 3500 6400 10033
54.
多个列的 GROUP BY SELECT department_id dept_id, job_id, SUM(salary) FROM employees GROUP BY department_id, job_id ORDER BY department_id;
55.
组函数的使用 在 SELECT子句中没有使用组函数的数据列,必须在 GROUP BY 子句中列出 : SELECT department_id, COUNT(last_name) FROM employees; SELECT department_id, job_id, COUNT(last_name) FROM employees GROUP BY department_id;
56.
组函数的使用 不能在 WHERE 子句中限制组,需要使用 HAVING 。 不能在 WHERE 子句中使用组函数。 错误: SELECT department_id, AVG(salary) FROM employees WHERE AVG(salary) > 8000 GROUP BY department_id; 正确: SELECT department_id, AVG(salary) FROM employees GROUP BY department_id HAVING AVG(salary) > 8000 ;
57.
组函数的嵌套 SELECT MAX(AVG(salary)) FROM employees GROUP BY department_id;
使用 USING 进行join 如果两个表中的列名相同,但数据类型不同,那么可以使用 using 进行对等 join. 使用 USING 只能指定的一个名字相同的列
62.
使用 ON 进行join 使用 ON 可以指定任意的条件或相关的列进行 join. 使用 ON 可以增加语句的易读性。 SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id FROM employees e JOIN departments d ON (e.department_id = d.department_id);
63.
使用 ON 进行join SELECT employee_id, city, department_name FROM employees e JOIN departments d ON d.department_id = e.department_id JOIN locations l ON d.location_id = l.location_id; …
64.
额外条件 SELECT e.employee_id,e.last_name, e.department_id, d.department_id, d.location_id FROM employees e JOIN departments d ON (e.department_id = d.department_id) AND e.manager_id = 149 ; 如要使用额外条件,可以使用 AND 或 WHERE 子句: SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id FROM employees e JOIN departments d ON (e.department_id = d.department_id) WHERE e.manager_id = 149 ; 或
左外连接 Left OuterJoin SELECT e.last_name, e.department_id, d.department_name FROM employees e LEFT OUTER JOIN departments d ON (e.department_id = d.department_id) ; …
70.
全外连接 Left OuterJoin SELECT e.last_name, d.department_id, d.department_name FROM employees e FULL OUTER JOIN departments d ON (e.department_id = d.department_id) ; …
NOT Exists 和 NOT in 如果子查询返回 NULL 值,则 NOT IN 返回假 当没有 null 值时 NOT in 与 not exists 效果相同 SELECT department_id, department_name FROM departments d WHERE NOT EXISTS (SELECT 'X' FROM employees WHERE department_id = d.department_id); 查找哪个部门没有员工 ( 表 employees 中有一行数据的 department_id 为 null ) SELECT department_id, department_name FROM departments d WHERE department_id NOT IN (SELECT department_id FROM employees); No rows selected.
76.
IN 、ANY 、 ALL <ANY 意谓着小于子查询返回结果的最大值 >ANY 意谓着大于子查询结果的最小值 =ANY 和 IN 的效果相同 ANY 中的子查询如果返回 0 行,则 <ANY , >ANY , =ANY , !=ANY , <=ANY 等操作都判断为假,主查询不返回数据 SELECT employee_id, last_name, job_id, salary FROM employees WHERE salary < ANY (SELECT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
77.
IN 、ANY 、 ALL <ALL 意谓着小于子查询返回结果的最小值 >ALL 意谓着大于子查询结果的最大值 ALL 中的子查询如果返回 0 行,则 <ALL , >ALL , =ALL , !=ALL , <=ALL 等操作都判断为真,主查询返回符合其他条件的数据 SELECT employee_id, last_name, job_id, salary FROM employees WHERE salary < ALL (SELECT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
UNION SELECT employee_id,job_id FROM employees UNION SELECT employee_id, job_id FROM job_history; … …
81.
UNION ALL SELECTemployee_id, job_id, department_id FROM employees UNION ALL SELECT employee_id, job_id, department_id FROM job_history ORDER BY employee_id; … …
成对比较子查询 返回与名字为 John的员工在同一个部门,且同一个领导的员工 SELECT employee_id, manager_id, department_id FROM empl_demo WHERE (manager_id, department_id) IN (SELECT manager_id, department_id FROM empl_demo WHERE first_name = 'John') AND first_name <> 'John';
89.
不成对比较子查询 返回与名字为 John的员工中任意一个领导相符和任意一个部门相符的员工 当名字为 John 多于一人时,与成对比较子查询的返回结果不同。 SELECT employee_id, manager_id, department_id FROM empl_demo WHERE manager_id IN (SELECT manager_id FROM empl_demo WHERE first_name = 'John') AND department_id IN (SELECT department_id FROM empl_demo WHERE first_name = 'John') AND first_name <> 'John';
使用关联子查询 SELECT column1 , column2 , ... FROM table1 WHERE column1 operator (SELECT column1, column2 FROM table2 WHERE expr1 = .expr2 ); outer outer SELECT e.employee_id, last_name,e.job_id FROM employees e WHERE 2 <= (SELECT COUNT(*) FROM job_history WHERE employee_id = e.employee_id );
93.
WITH 使用 WITH,可以在查询中多次引用相同的子查询 使用 WITH 返回的结果存放在临时空间 在复杂的查询中适当使用 WITH ,可以提高性能
94.
WITH 示例 WITH dept_costs AS ( SELECT d.department_name, SUM(e.salary) AS dept_total FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY d.department_name), avg_cost AS ( SELECT SUM(dept_total)/COUNT(*) AS dept_avg FROM dept_costs ) SELECT * FROM dept_costs WHERE dept_total > (SELECT dept_avg FROM avg_cost ) ORDER BY department_name;
INSERT INSERT INTOdepartments VALUES (100, 'Finance', NULL, NULL); INSERT INTO departments (department_id, department_name) VALUES (30, 'Purchasing'); INSERT INTO sales_reps(id, name, salary, commission_pct) SELECT employee_id, last_name, salary, commission_pct FROM employees INSERT INTO employees (employee_id,hire_date) VALUES (113,SYSDATE);
98.
多表 INSERT 多表插入有以下种类: 无条件 INSERT 有条件 INSERT ALL 旋转 (Pivoting) INSERT 条件 INSERT FIRST
99.
Unconditional INSERT ALLINSERT ALL INTO sal_history VALUES(EMPID,HIREDATE,SAL) INTO mgr_history VALUES(EMPID,MGR,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL, manager_id MGR FROM employees WHERE employee_id > 200;
100.
Unconditional INSERT ALLINSERT ALL INTO sal_history VALUES(EMPID,HIREDATE,SAL) INTO mgr_history VALUES(EMPID,MGR,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL, manager_id MGR FROM employees WHERE employee_id > 200;
101.
Conditional INSERT ALLINSERT ALL WHEN HIREDATE < ' 01-JAN-95 ' THEN INTO emp_history VALUES(EMPID,HIREDATE,SAL) WHEN COMM IS NOT NULL THEN INTO emp_sales VALUES(EMPID,COMM,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL, commission_pct COMM FROM employees
102.
Conditional INSERT FIRSTINSERT FIRST WHEN salary < 5000 THEN INTO sal_low VALUES (employee_id, last_name, salary) WHEN salary between 5000 and 10000 THEN INTO sal_mid VALUES (employee_id, last_name, salary) ELSE INTO sal_high VALUES (employee_id, last_name, salary) SELECT employee_id, last_name, salary FROM employees
Pivoting INSERT INSERTALL INTO sales_info VALUES (employee_id,week_id,sales_MON) INTO sales_info VALUES (employee_id,week_id,sales_TUE) INTO sales_info VALUES (employee_id,week_id,sales_WED) INTO sales_info VALUES (employee_id,week_id,sales_THUR) INTO sales_info VALUES (employee_id,week_id, sales_FRI) SELECT EMPLOYEE_ID, week_id, sales_MON, sales_TUE, sales_WED, sales_THUR,sales_FRI FROM sales_source_data;
105.
UPDATE UPDATE employeesSET department_id = 50 WHERE employee_id = 113; UPDATE copy_emp SET department_id = 110; UPDATE employees SET department_id = 50 WHERE employee_id = null; UPDATE employees SET job_id = (SELECT job_id FROM employees WHERE employee_id = 205) WHERE employee_id = 113;
106.
UPDATE 中的关联子查询 UPDATE table1 alias1 SET column = (SELECT expression FROM table2 alias2 WHERE alias1.column = alias2.column );
107.
DELETE DELETE FROMdepartments WHERE department_name = ‘Finance'; DELETE FROM copy_emp; DELETE FROM employees WHERE department_id = (SELECT department_id FROM departments WHERE department_name LIKE '%Public%');
108.
DELETE 中的关联子查询 DELETEFROM table1 alias1 WHERE column operator (SELECT expression FROM table2 alias2 WHERE alias1.column = alias2.column);
读一致性的实现 SELECT * FROM userA.employees; UPDATE employees SET salary = 7000 WHERE last_name = 'Grant'; Data blocks Undo segments Changed and unchanged data Before change (“old” data) 用户 A 用户 B Read- consistent image
119.
SELECT 中的 FORUPDATE 子句 锁定符合条件的数据行 锁可以被 COMMIT 或 ROLLBACK 释放 当有一个用户正在修改数据,而另一个用户进行 SELECT FOR UPDATE 去查询这部分数据时,会进行等待,直到第一个用户释放锁。 在多表查询时,使用 for update of table1.column_name 时,只有指定列相关的表的一部分符合条件数据被锁定。 SELECT employee_id, salary, commission_pct, job_id FROM employees WHERE job_id = 'SA_REP' FOR UPDATE ORDER BY employee_id;
CREATE TABLE DESCRIBEdept CREATE TABLE dept (deptno NUMBER(2), dname VARCHAR2(14), loc VARCHAR2(13), create_date DATE DEFAULT SYSDATE );
125.
引用其他用户的表 USERB USERASELECT * FROM userB.employees; SELECT * FROM userA.employees;
126.
CTAS (Create TableAs Select) CREATE TABLE dept80 AS SELECT employee_id, last_name, salary*12 ANNSAL, hire_date FROM employees WHERE department_id = 80; DESCRIBE dept80
127.
数据类型 未经处理的类型 RAWand LONG RAW 二进制数据类型 (up to 4 GB) BLOB 存储在外部文件的二进制数据类型 (up to 4 GB) BFILE 日期类型 DATE 变长的字符类型 (up to 2 GB) LONG 字符类型 (up to 4 GB) CLOB 代表表中数据行的唯一地址 ROWID 定长的字符数据 CHAR( size ) 变长的数值类型 NUMBER( p , s) 变长的字符类型 VARCHAR2( size ) 描述 Data Type
128.
数据类型 存储时间间隔的类型 INTERVALYEAR TO MONTH 存储时间间隔的类型 INTERVAL DAY TO SECOND 较精细的日期类型 TIMESTAMP 描述 Data Type
视图 VIEW简单视图与复杂视图: Yes No No One Simple Views Yes 包含函数 Yes 使用 group by One or more 相关表的个数 Not always 通过视图进行 DML 操作 Complex Views 特点
141.
创建视图 CREATE [ORREPLACE] [FORCE| NOFORCE ] VIEW view [( alias [, alias ]...)] AS subquery [WITH CHECK OPTION [CONSTRAINT constraint ]] [WITH READ ONLY [CONSTRAINT constraint ]]; CREATE OR REPLACE VIEW empvu80 (id_number, name, sal, department_id) AS SELECT employee_id, first_name || ' ' || last_name, salary, department_id FROM employees WHERE department_id = 80;
142.
对视图进行 DML 操作的规则对简单视图总是可以进行 DML 操作 如果视图含有以下内容时,不能 删除 数据行 : 组函数 Group functions 有 GROUP BY 子句 有 DISTINCT 有伪列 ROWNUM
143.
对视图进行 DML 操作的规则如果视图含有以下内容时,不能 修改 数据行 : 组函数 Group functions 有 GROUP BY 子句 有 DISTINCT 有伪列 ROWNUM 以表达式定义的列 (for example, SALARY * 12 )
144.
对视图进行 DML 操作的规则如果视图含有以下内容时,不能 插入 数据行 : 组函数 Group functions 有 GROUP BY 子句 有 DISTINCT 有伪列 ROWNUM 以表达式定义的列 (for example, SALARY * 12 ) 基表中的 NOT NULL 列在视图中不可见时
145.
使用 WITH CHECKOPTION WITH CHECK OPTION 可以限制 DML 操作 : CREATE OR REPLACE VIEW empvu20 AS SELECT * FROM employees WHERE department_id = 20 WITH CHECK OPTION CONSTRAINT empvu20_ck ;
146.
使用 WITH READONLY WITH READ ONLY 选项防止 DML 操作 CREATE OR REPLACE VIEW empvu10 (employee_number, employee_name, job_title) AS SELECT employee_id, last_name, job_id FROM employees WHERE department_id = 10 WITH READ ONLY ;
创建序列 CREATE SEQUENCE sequence [INCREMENT BY n ] [START WITH n ] [{MAXVALUE n | NOMAXVALUE }] [{MINVALUE n | NOMINVALUE }] [{CYCLE | NOCYCLE }] [{CACHE n | NOCACHE}];
修改序列 ALTER SEQUENCEdept_deptid_seq INCREMENT BY 20 MAXVALUE 999999 NOCACHE NOCYCLE; 只有以后的序列值受影响 如果要更改起始值,只能重新创建序列 会进行一些验证 要删除序列,使用 DROP 语句 : DROP SEQUENCE dept_deptid_seq;
创建索引 在一个或多个列上创建索引 :以下索引可以根据 last_name 列的条件,加快查询: CREATE INDEX emp_last_name_idx ON employees(last_name); CREATE [UNIQUE][BITMAP]INDEX index ON table ( column [, column ]...);
赋予对象权限 将查询 EMPLOYEES的权限赋予 demo 用户 : 将特定列的 UPDATE 权限赋予用户和角色: GRANT select ON employees TO demo; GRANT update (department_name, location_id) ON departments TO demo, manager;
172.
回收对象权限 使用 REVOKE 收回权限 通过 WITH GRANT OPTION 赋给其他用户的权限也同时收回 . REVOKE {privilege [, privilege...]|ALL} ON object FROM {user[, user...]|role|PUBLIC} [CASCADE CONSTRAINTS];