20250328
主键约束 不可为空 唯一
唯一性约束 可为空 唯一
ADD 数据列名 数据类型 #添加新的列
DROP COLUMN 列名 #删除列
ALTER COLUMN 列名 新的数据类型 #改该列的数据类型,只能加长不能缩短
以下是关于 SQL 中 UPDATE、DELETE 和 TRUNCATE 语句的使用方法及注意事项的详细说明:
1. UPDATE 语句
用途:修改表中已有的数据。
基本语法:
UPDATE 表名
SET 列1 = 值1, 列2 = 值2, …
WHERE 条件;
示例:
— 将用户ID为1的用户的年龄更新为25
UPDATE users
SET age = 25
WHERE user_id = 1;
— 同时更新多个字段
UPDATE employees
SET salary = 50000, department = ‘HR’
WHERE employee_id = 101;
注意事项:
- 务必使用 WHERE 子句:如果省略 WHERE,表中所有行的指定列都会被更新!
- 事务安全:在生产环境中,建议在更新前开启事务(如 BEGIN TRANSACTION),以便在出错时回滚。
- 备份数据:对关键数据操作前,建议先备份(如 CREATE TABLE users_backup AS SELECT * FROM users)。
2. DELETE 语句
用途:删除表中的数据行。
基本语法:
DELETE FROM 表名
WHERE 条件;
示例:
— 删除用户ID为1的记录
DELETE FROM users
WHERE user_id = 1;
— 删除所有年龄大于60的记录
DELETE FROM employees
WHERE age > 60;
注意事项:
- WHERE 子句同样关键:省略 WHERE 会删除表中所有数据!
- 性能问题:删除大量数据时,DELETE 会逐行操作并记录日志,可能较慢。
- 触发器:DELETE 会触发 DELETE 类型的触发器(如果有)。
- 事务与备份:同 UPDATE,建议操作前备份并使用事务。
3. TRUNCATE 语句
用途:快速删除表中所有数据(不可逆操作)。
基本语法:
TRUNCATE TABLE 表名;
示例:
TRUNCATE TABLE logs; — 清空 logs 表的所有数据
注意事项:
- 不可逆:TRUNCATE 会直接删除所有数据,且无法通过事务回滚(除非在支持事务的数据库中显式使用 ROLLBACK)。
- 效率高:不逐行删除,而是释放数据页,日志记录少,速度远快于 DELETE。
- 重置自增列:会将自增列(如 AUTO_INCREMENT 或 IDENTITY)重置为初始值。
- 权限要求:通常需要更高权限(如 DROP 权限)。
- 不触发触发器:不会触发 DELETE 触发器。
DELETE vs TRUNCATE 对比
特性 | DELETE | TRUNCATE |
删除范围 | 可以有条件删除部分数据 | 只能删除全部数据 |
日志记录 | 逐行记录日志,较慢 | 整体释放数据页,速度快 |
事务回滚 | 可回滚(需在事务中) | 通常不可回滚 |
自增列重置 | 不重置自增列 | 重置自增列到初始值 |
触发器 | 触发 DELETE 触发器 | 不触发 |
语法复杂度 | 支持复杂条件(如子查询) | 仅能清空整个表 |
使用建议
- 谨慎操作:在生产环境执行前,先用 SELECT * FROM 表名 WHERE 条件 确认影响范围。
- 优先使用 TRUNCATE:如果需要清空表且无需条件,优先选择 TRUNCATE 以提高效率。
- 避免全表操作:对大表执行 DELETE 或 TRUNCATE 时,注意锁表和性能问题。
- 权限控制:严格限制对 TRUNCATE 的权限,防止误操作。
DISTINCT查询时去重
SELECT DISTINCT FROM WHERE GROUP BY HAVING ORDER BY
在 SQL 中,DISTINCT 关键字用于在查询结果中去除重复的行。当与其他子句(如 WHERE、GROUP BY、HAVING、ORDER BY)结合时,需注意它们的执行顺序和逻辑关系。以下是具体用法及示例:
1. 基本语法
SELECT DISTINCT column1, column2, …
FROM table_name
WHERE condition
GROUP BY column1, column2, …
HAVING group_condition
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC];
2. 各子句与 DISTINCT 的结合使用
(1) SELECT DISTINCT 基础去重
- 作用:返回指定列的唯一组合值。
- 示例:
- — 查询不重复的部门名称
SELECT DISTINCT department
FROM employees;– 查询部门和职位的唯一组合
SELECT DISTINCT department, position
FROM employees;
(2) WHERE 子句过滤后去重
- 执行顺序:先执行 WHERE 过滤数据,再对结果去重。
- 示例:
- — 查询工资高于 5000 的员工所在城市(去重)
SELECT DISTINCT city
FROM employees
WHERE salary > 5000;
(3) GROUP BY 与 DISTINCT 的异同
- 区别:
- DISTINCT 直接去重,返回所有列的唯一值。
- GROUP BY 用于分组聚合(如 COUNT, SUM)。
- 示例:
- — 使用 GROUP BY 统计每个部门的人数(无需 DISTINCT)
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department;– 若同时需要去重和分组,需明确逻辑(如统计不同职位的数量)
SELECT department, COUNT(DISTINCT position) AS unique_positions
FROM employees
GROUP BY department;
(4) HAVING 过滤分组后的结果
- 作用:对 GROUP BY 分组后的结果进行条件过滤。
- 示例:
- — 查询员工数超过 5 人的部门(需 GROUP BY)
SELECT department
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;– 结合 DISTINCT 和 HAVING(较少见)
SELECT department, COUNT(DISTINCT city) AS cities
FROM employees
GROUP BY department
HAVING cities > 2;
(5) ORDER BY 排序去重结果
- 作用:对最终结果按指定列排序。
- 示例:
- — 按注册时间降序排列不重复的用户名
SELECT DISTINCT username
FROM users
ORDER BY registration_date DESC;
3. 注意事项
- 多列去重:DISTINCT 作用于所有列的组合,而非单列。例如:
- SELECTDISTINCT department, position FROM employees;
— 结果中 department 和 position 的组合是唯一的。
- 性能问题:DISTINCT 可能导致全表扫描和排序,大数据量时需谨慎使用。
- 避免混淆:
-
- DISTINCT 不适用于聚合函数内部(但 COUNT(DISTINCT column) 是合法的)。
- 不能同时使用 DISTINCT 和 GROUP BY 对同一列去重(逻辑冲突)。
- 替代方案:若仅需去重,优先用 DISTINCT;若需分组统计,使用 GROUP BY。
4. 完整示例
— 查询工资高于 5000 的员工所在城市(去重),并按城市名排序
SELECT DISTINCT city
FROM employees
WHERE salary > 5000
ORDER BY city;
— 统计每个部门的不同职位数量,并筛选职位数超过 2 的部门
SELECT department, COUNT(DISTINCT position) AS unique_positions
FROM employees
GROUP BY department
HAVING unique_positions > 2;
SELECT * from STUDENT t where ROWNUM<0; #最近六条记录
SELECT * FROM STUDENT WHERE SNAME LIKE '%张%';
SELECT * FROM STUDENT WHERE SNAME LIKE '%张__'; #下划线代表一个字符 百分号代表任意字符
select* from STU1 t
oDBCImporter Command Window
where t.birthday between to_date(2000-01-01',yyyy-mm-d') and to_date(2003/12/31','yyy/mm/dd')
SELECT count(*) from STUDENT;
ASC为升序,DESC为降序
‘=’是精确匹配,不可用过量通配符
‘LIKE’是模糊匹配
11-12题
11
(1)ALTER TABLE STUDENT ADD NATION VARCHAR2(20);
(2)ALTER TABLE STUDENT DROP COLUMN NATION;
(3)INSERT INTO GRADE VALUES (‘2021110′,’3′,’80’);
(4)UPDATE GRADE SET GMARK=’70’ WHERE SNO=’2021110′;
(5)DELETE FROM GRADE WHERE SNO=’2021110′;
(6)CREATE INDEX IX_CLASS ON GRADE(CNO ASC);
(7)DROP INDEX IX_CLASS;/*这是ORACLE的写法*/
12
(1)SELECT DISTINCT CNO FROM GRADE;
(2)SELECT * FROM STUDENT T WHERE T.SsEX=’女’ AND T.CLNO=’20311′;
(3)SELECT T.SNAME,T.SSEX,T.SBIRTH FROM STUDENT T WHERE T.CLNO=’20311′ OR T.CLNO=’20312′;
(4)SELECT * FROM STUDENT T WHERE T.SNAME LIKE ‘李%’;
(5)SELECT *
FROM STUDENT
WHERE CLNO = (SELECT CLNO FROM STUDENT WHERE SNAME = ‘李勇’);
(6)SELECT
MAX(GMARK) AS 最高分,
MIN(GMARK) AS 最低分,
AVG(GMARK) AS 平均分
FROM GRADE
WHERE CNO = (SELECT CNO FROM COURSE WHERE CNAME = ‘操作系统’);
(7)SELECT COUNT(DISTINCT SNO)
FROM GRADE;
(8)SELECT COUNT(DISTINCT SNO)
FROM GRADE WHERE CNO=(SELECT CNO FROM COURSE WHERE CNAME=’操作系统’);
(9)SELECT SNAME
FROM STUDENT
WHERE CLNO IN (
SELECT CLNO
FROM CLASS
WHERE SPECIAL = ‘软件工程’
AND TRIM(INYEAR) = ‘2020’ — 处理 INYEAR 是 CHAR(8) 的空格填充问题
)
AND SUBSTR(SNO, 1, 7) NOT IN ( — 匹配 GRADE.SNO 的 CHAR(7) 长度
SELECT SNO FROM GRADE
);
/*步入迷惑*/
(10)
SELECT
C.CNO,
C.CNAME,
C.CPNO AS 直接先修课号,
(SELECT CPNO FROM COURSE WHERE CNO = C.CPNO) AS 间接先修课号,
(SELECT CNAME FROM COURSE
WHERE CNO = (SELECT CPNO FROM COURSE WHERE CNO = C.CPNO)) AS 间接先修课名
FROM COURSE C;