数据库操作
CRUD指令
1. 对库的操作
DROP DATABASE hsp_db01 #删除数据库
CREATE DATABASE hsp_db01#使用指令创建数据库
#创建一个使用utf8字符集的hsp_db02数据库
CREATE DATABASE hsp_db02 CHARACTER SET utf8
#创建一个utf8字符集,并带校对规则的hsp_db03数据库
CREATE DATABASE hsp_db03 CHARACTER SET utf8 COLLATE utf8_bin
#校对规则,utf8_bin区分大小写,默认utf8_general_ci不区分大小写
SELECT * FROM t1 WHERE NAME = 'tom'#查询的语句`t1`
#演示删除和查询数据库
#查看当前数据库服务器中的所有数据库
SHOW DATABASES
#查看前面创建的hsp_dbo1数据库的定义信息
SHOW CREATE DATABASE hsp_db01
#删除前面创建的hsp_db01数据库
DROP DATABASE hsp_db01
#备份与恢复数据
#备份 dump转存 backup备份
#这个备份文件就是对应的sql语句(在控制台)
mysqldump -u root -p -B hsp_db02 hsp_db03 > d:\\bak.sql
DROP DATABASE hsp_db03;
#恢复数据库(注意:进入mysql命令行再执行)
source d:\\bak.sql
#第二个恢复方法,执行 d:\\bak.sql的每一条sql语句(复制粘贴到sqlyog中执行)
#只想备份某个表
# mysqldump -u root -p -B hsp_db02 hsp_db03 > d:\\bak.sql
#把上面的 -B 去掉,后面可接数据库和表名
mysqldump -u root -p hsp_db02 t1 > d:\\bak1.sql
#删除表(table)
DROP TABLE t1
#恢复表
source d:\\bak1.sql
删除和恢复表的细节
#恢复表前,得先进对应的数据库(用use)
use hsp_db03
2.对表的操作
1.创建表
-- 创建表
CREATE TABLE table_name(INT id);
-- 添加一条记录
INSERT INTO table_name VALUES();
2.修改表
#修改表的操作练习
-- 员工表 emp 的上增加一个 image 列,varchar 类型(要求在 resume 后面)
ALTER TABLE emp
ADD image VARCHAR(32) NOT NULL DEFAULT '' AFTER RESUME
DESC employee -- 显示表结构,可以查看表的所有列
-- 修改 job 列,使其长度为 60。
ALTER TABLE emp
MODIFY job VARCHAR(60) NOT NULL DEFAUlt
ALTER TABLE emp DROP sex -- 删除 sex 列。
RENAME TABLE emp TO employee-- 表名改为 employee。
ALTER TABLE employee CHARACTER SET utf8 -- 修改表的字符集为 utf8
-- 列名 name 修改为 user
ALTER TABLE employee CHANGE `name` user_name VARCHAR(64) NOT NULL DEFAULT '' -- 列名 name 修改为user_name
DESC employee
3. 修改列
update tab_name set col = xxx
where 条件
函数
1. 统计函数
SUM AVG MAX MIN COUNT(*) COUNT(列)
2.分组统计
非常重要!!!
group by 某列 + having (用于约束)
having区别where,where 放在 from table_name 后面,作用是过滤(会使得行变少) 而having是配合 group by 使用的,作为约束条件 (group by 相当于将一个group合成一个)
后来补充:
- where 是删除不满足条件的行(没有group by 的情况下,可以把原表看成一个打组,where是对这个组内的行进行检索)(where的作用域是组内,作用对象是行)
- having 是删除不满足组,作用域是整个表,作用对象是组(以组为单位进行删除)
如何理解分组?像剥洋葱一样,一层一层地
3.字符串函数
-- 演示字符串相关函数的使用 , 使用 emp 表来演示 -- CHARSET(str) 返回字串字符集 SELECT CHARSET(ename) FROM emp; -- CONCAT (string2 [,... ]) 连接字串, 将多个列拼接成一列 SELECT CONCAT (ename,' job is ', job) FROM emp; -- INSTR (string ,substring ) 返回 substring 在 string 中出现的位置,没有返回 0 -- dual 亚元表, 系统表 可以作为测试表使用 SELECT INSTR('hanshunping', 'ping') ; -- UCASE (string2 ) 转换成大写 SELECT UCASE('abc') FROM DUAL -- LCASE (string2 ) 转换成小写 SELECT LCASE(ename) FROM emp; -- LEFT (string2 ,length )从 string2 中的左边起取 length 个字符 -- RIGHT (string2 ,length ) 从 string2 中的右边起取 length 个字符 SELECT LEFT(ename, 2) FROM emp; -- LENGTH (string )string 长度[按照字节] SELECT LENGTH(ename) FROM emp; -- REPLACE (str ,search_str ,replace_str ) -- 在 str 中用 replace_str 替换 search_str -- 如果是 manager 就替换成 经理 SELECT ename, REPLACE(job,'MANAGER', '经理') AS replace_ FROM emp; -- STRCMP (string1 ,string2 ) 逐字符比较两字串大小 SELECT STRCMP('hsp123', 'hsp12') FROM DUAL; SELECT STRCMP('hsp', 'hsp') FROM DUAL; -- SUBSTRING (str , position [,length ]) -- 从 str 的 position 开始【从 1 开始计算】,取 length 个字符 -- 从 ename 列的第一个位置开始取出 2 个字符 SELECT SUBSTRING(ename, 1, 2) FROM emp -- LTRIM (string2 ) RTRIM (string2 ) TRIM(string) -- 去除前端空格或后端空格 SELECT LTRIM(' 韩顺平教育') FROM DUAL; SELECT RTRIM('韩顺平教育 ') FROM DUAL; SELECT TRIM(' 韩顺平教育 ') FROM DUAL; -- 练习: 以首字母小写的方式显示所有员工 emp 表的姓名 -- 方法一 我的思路,用替换的方法,用第一个字母的小写去替换 SELECT REPLACE( ename,SUBSTRING(ename, 1, 1) , LCASE(SUBSTRING(ename, 1, 1))) FROM emp; -- 方法二 老韩 拼接 SELECT CONCAT (LCASE(LEFT(ename, 1)), SUBSTRING(ename, 2)) FROM emp;
4.数学函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8UhTrpv5-1650856479843)(https://raw.githubusercontent.com/PigBrother6/picgo/main/202204162121591.png)]
-- -- 演示数学相关函数 -- ABS(num) 绝对值 SELECT ABS(-10) FROM DUAL; -- BIN (decimal_number )十进制转二进制 SELECT BIN(10) FROM DUAL; -- CEILING (number2 ) 向上取整, 得到比 num2 大的最小整数 SELECT CEILING(-1.1) FROM DUAL; -- CONV(number2,from_base,to_base) 进制转换 -- 下面的含义是 8 是十进制的 8, 转成 2 进制输出 SELECT CONV(8, 10, 2) FROM DUAL; -- 下面的含义是 8 是 16 进制的 8, 转成 2 进制输出 SELECT CONV(16, 16, 10) -- FLOOR (number2 ) 向下取整,得到比 num2 小的最大整数 SELECT FLOOR(-1.1) FROM DUAL; -- FORMAT (number,decimal_places ) 保留小数位数(四舍五入) SELECT FORMAT(78.125458,2) FROM DUAL; -- HEX (DecimalNumber ) 转十六进制 -- LEAST (number , number2 [,..]) 求最小值 SELECT LEAST(0,1, -10, 4) FROM DUAL; -- MOD (numerator ,denominator ) 求余 SELECT MOD(-10, 3) FROM DUAL; -- RAND([seed]) RAND([seed]) 返回随机数 其范围为 0 ≤ v ≤ 1.0 -- 老韩说明 -- 1. 如果使用 rand() 每次返回不同的随机数 ,在 0 ≤ v ≤ 1.0 -- 2. 如果使用 rand(seed) 返回随机数, 范围 0 ≤ v ≤ 1.0, 如果 seed 不变, -- 该随机数也不变了 SELECT RAND(1) FROM DUAL;
5.日期函数
<img src="https://raw.githubusercontent.com/PigBrother6/picgo/main/202204170829674.png" alt="image-20220417082942026" style="zoom: 50%;" />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GvTXd2Oy-1650856479844)(https://raw.githubusercontent.com/PigBrother6/picgo/main/202204170832344.png)]
![image-20220417083424978](https://img-blog.csdnimg.cn/img_convert/c74cfe77dab5366092a13ce5a9dcffb1.png) ```mysql -- 日期时间相关函数 -- CURRENT_DATE ( ) 当前日期 SELECT CURRENT_DATE() FROM DUAL -- CURRENT_TIME ( )当前时间 SELECT CURRENT_TIME() FROM DUAL; -- CURRENT_TIMESTAMP ( ) 当前时间戳 SELECT CURRENT_TIMESTAMP() FROM DUAL; -- 创建测试表 信息表 CREATE TABLE mes( id INT, content VARCHAR(30), send_time DATETIME); -- 添加一条记录 INSERT INTO mes VALUES(1, '北京新闻', CURRENT_TIMESTAMP()); INSERT INTO mes VALUES(2, '上海新闻', NOW()); INSERT INTO mes VALUES(3, '广州新闻', NOW()); SELECT * FROM mes; SELECT NOW() FROM DUAL; -- 上应用实例 -- 显示所有新闻信息,发布日期只显示 日期,不用显示时间. SELECT id, content, DATE(send_time)FROM mes; -- 请查询在 10 分钟内发布的新闻, 思路一定要梳理一下. SELECT * FROM mes WHERE DATE_ADD(send_time,INTERVAL 10 MINUTE) > NOW(); SELECT * FROM mes WHERE DATE_SUB(NOW(), INTERVAL 12 MINUTE) < send_time; -- 请在 mysql 的 sql 语句中求出 2011-11-11 和 1990-1-1 相差多少天 SELECT DATEDIFF('2011-11-11', '1990-01-01') FROM DUAL; -- 请用 mysql 的 sql 语句求出你活了多少天? [练习] 1986-11-11 出生 SELECT DATEDIFF(NOW(),'1986-11-11') FROM DUAL; -- 如果你能活 80 岁,求出你还能活多少天.[练习] 1986-11-11 出生 SELECT DATEDIFF(DATE_ADD(NOW(),INTERVAL 80 YEAR),NOW()) FROM DUAL; SELECT TIMEDIFF('10:11:11', '06:10:10') FROM DUAL -- YEAR|Month|DAY| DATE (datetime ) SELECT YEAR(NOW()) FROM DUAL; SELECT MONTH(NOW()) FROM DUAL; SELECT DAY(NOW()) FROM DUAL; SELECT MONTH('2013-11-10') FROM DUAL; SELECT UNIX_TIMESTAMP() FROM DUAL; -- FROM_UNIXTIME() : 可以把一个 unix_timestamp 秒数[时间戳],转成指定格式的日期 -- %Y-%m-%d 格式是规定好的,表示年月日 -- 意义:在开发中,可以存放一个整数,然后表示时间,通过 FROM_UNIXTIME 转换 SELECT FROM_UNIXTIME(1618483484, '%Y-%m-%d') FROM DUAL; SELECT FROM_UNIXTIME(1618483100, '%Y-%m-%d %H:%i:%s') FROM DUAL; SELECT * FROM mysql.user \G ```
6.加密函数
7. 流程控制函数😄 😢
-
IF (expression1, exper2 , expr3)
如果expr1 is ture ,return expr2,otherwise,expr3;
-
IFNULL (expr1 , expr2)
if expr1 isn't null,return expr1;otherwise,expr2;
-
SELECT
CASE
WHEN
expr1then
expr11when
expr2then
expr22else
expr3if expr1 is true,return expr11;if expr2 is true ,return expr 22;else return expr3 very like if elif else;
查询
1. 查询增强 🚀
- WHERE 对表的某列进行比较判断 = < > LIKE
- LIKE 模糊查询 通配符: _ 一个下划线通配一个字符; %百分号通配任意个字符
- DESC <table_name> 查询表结构
- ORDER BY ASCE/DESC 升序/降序
- ORDER BY colunm1 ORDER BY column2 先排column1 再排column2
2. 分页查询📖
-
SELECT … limit start , rows
表示从 start+1 开始取,取 rows 行 每页可放(rows - start)行
推导公式
SELECT ... LIMIT(每页记录数 * (第几页 - 1), 每页记录数)
3. 分组增强👩👧👦
- GROUP BY … + HAVING …
4. 多子句查询
- 如果select语句同时包含group by ,having, limit ,order by ,那么他们的顺序是group by,having , order ,limit
多表
1. 多表笛卡尔集
- 当执行
select ... from table1 from table2
时2 , 两个不同的表合并在一起; - 合并的规则是,用 table 1的行(m 行 q列)和 table2 (n 行 p列)的行组合,列则是两个表的所有列都列出来(即使列名相同,也会分开列出来);
- 最后合并后的表有 (m * n) 行,(q + p)列
举例,根据emp表的deptno,去dept表查询dname
select ename,sal,dname from emp from dept where emp.deptno = dept.deptno
2. 多表查询
多表查询的条件不能少于 表的个数-1, 否则会出现笛卡尔集
一般用where 来作为查询条件
3. 自连接🤳
自连接
: 自连接是指在同一张表的连接查询
步骤:
- 给表取别名,不用加
AS
- 用表的别名来操作
个人技巧:
- 对于自连接(或者多表的操作),可以先将原始的两张表直接合并
- 观察合并后的笛卡尔表,判断约束条件(写where)
4. 表子查询
4.1 单/多行子查询
**子查询:**嵌入在其他 sql 语句中的 select 语句,也叫嵌套查询
-
单行子查询
只返回一行数据的子查询语句
-
多行子查询
返回多行数据的子查询语句,使用关键字
IN
\
个人技巧:(容易懵逼)
- 区分是多表查询还是子查询(很重要!)👿
- 多表查询要用到其他表的列,而子查询不会用到其他表
- 多行子查询 select 出来的列有多行,需要用
IN
来遍历
4.2多列查询
案例
如何查询与smith的部门和岗位完全相同的所有雇员,且不包含smith本人
代码
-
先查smith所在的部门和岗位
select job, deptno from emp where ename = 'ALLEN';
-
把查询结果当成临时表(一行多列)
select job, deptno, ename from emp where(job, deptno) = (select job, deptno from emp where ename = 'ALLEN') AND ename != 'ALLEN'
语法
where (job, deptno) = select (job, deptno) from emp
where ename = 'ALLEN'
4.3 总结🍎
- 多表查询,要找到关联条件
- group by 一定要记得 select 这个
- select 子查询返回的是一个临时表,虽然是单列,但是还是表!
5. 表复制和去重
-
表复制
蠕虫复制
NSERT INTO my_tab01 SELECT * FROM my_tab01;
-
表去重
- (1) 先创建一张临时表 my_tmp , 该表的结构和 my_tab
- (2) 把 my_tmp 的记录 通过 distinct 关键字 处理后 把记录复制
- (3) 清除掉 my_tab02
- (4) 把 my_tmp 表的记录复制到 my_tab02
- (5) drop 掉 临时表 my_tmp
注意 : distinct 只是在显示时去重,并不会剔除掉重复的数据
6. 合并查询
**先注意:**合并查询和where and 的效果并不一样,不服来代码验证
**合并查询:**即合并查询的结果(去重或不去重)。使用 union
(去重), union all
(不去重)
代码演示
SELECT ename,sal,job FROM emp WHERE sal>2500 -- 5
SELECT ename,sal,job FROM emp WHERE job='MANAGER' -- 3
SELECT ename,sal,job FROM emp WHERE job='MANAGER' AND sal > 2500 -- 2
SELECT ename,sal,job FROM emp WHERE sal>2500 -- 5
UNION ALL
SELECT ename,sal,job FROM emp WHERE job='MANAGER' -- 3
-- >8条
SELECT ename,sal,job FROM emp WHERE sal>2500 -- 5
UNION
SELECT ename,sal,job FROM emp WHERE job='MANAGER' -- 3
-- <8条
7. 外连接 📤
提出问题:❓
- 前面所学的,都是通过 where 子句对两张表或多张表,形成的笛卡尔积进行筛选,根据关联条件,显示所有匹配记录,匹配不上的不显示(问题所在)
- 再如,没有员工的部门也要显示出来
外连接
- 左外连接: 如果左侧的表完全显示,则是左外连接
- 右外连接: 同理
代码
-
select from tab1 left join tab2 on 条件
-
总结: 添加 left join , where 改成 on
8. 主键
primary key
基本使用: 字段名 字段类型 primary key
作用 :用于唯一得标示表行得数据,当定义主键约束时,该列不能重复
主键分类
-
单主键
直接指定一个字段为 primary key
-
复合主键
指定两个或多个字段为 复合主键 ;在最后指定
CREATE TABLE t18 (id INT , `name` VARCHAR(32), email VARCHAR(32), PRIMARY KEY (id, `name`) -- 这里就是复合主键 );
9. mysql约束
-
not Null
如果在列上定义了not null ,那么当插入数据时,必须为列提供数据
字段名 字段类型 not null
-
unique
当定义了唯一约束后,该列的值是不能重复的
字段名 字段类型 unique
细节:
- 如果没有指定not null,则unique 字段可以有多个null;其他的非null只能有一个
- 一张表可以有多个unique字段(和主键不一样,主键只有一个)
- 如果一个列(字段), 是 unique not null 使用效果类似 primary(单主键)
-
foreign key(外键)
-
用于定义主表和从表之间的关系
-
外键约束要定义在从表上,主表则必须具有主键或unique 约束
-
当定义外键约束后,要求外键列数据必须在主表的主键列存在或是外键数据为null (学生/班级)
可以类比地理解主键和外键的关系(用班级和学生) 学生 有 id name class_id 三个字段 (class_id 作为 外键) 班级有 id name add 三个字段 (id 作为 主键) 如果想把某个同学加入当学生表中,只有当学生的 class_id(外键)存在于班级的 id列(主键列)时, 或 class_id 为null时,才能添加进去 怎么理解呢?首先,有当学生的 class_id(外键)存在于班级的 id列(主键列)时,这个好理解!你只有是属于某个班级的才能被加进去嘛;然后,class_id为null时,才能添加进去,为什么?可以这样想?一个学生转学来了这个学校,但是还没分配班级,所以处于待定状态。 最后,那为什么不存在于主键列就加不进去? 可以理解为,要么你已经有明确的班级分配,要么就是待定。然而你却写了一个不存在班级号,显然是乱来的
-
代码
在从表中指定主外键关系,
外键 外键列 references 主键 主表(主表列)
FOREIGN KEY (class_id) REFERENCES my_class(id)
-
细节
- 表的类型是 innodb 才支持外键
- 外键字段允许为null 才能添加null (而且只能加一个 null 本人测试过)
- 一旦建立主外表关系,数据就不能随便删除(主键列的元素 要 从表的外键列中 没有指向这个元素 的元素 才可以删除)
-
-
check
mysql5.7 目前还不支持 check ,只做语法校验,但不会生效
其他
1. 自增长
介绍: 在某张表中,我们希望存在一个 id 列(整数),我们希望在记录的时候该列从1开始,自动地增长
代码
字段名 整型 primary key auto_increment
-- 增加 自增长字段的方式
insert into xxx (字段1 字段2 ...) values (null, '值1' ...)
insert into xxx (字段2 ...) values ('值1' ,'值2'...)
insert into xxx values (null, '值1' ...)
-- 修改默认的自增长开始值
ALTER TABLE t25 AUTO_INCREMENT = 100
总结:其实 value 中对应自增长的那个值就是本条记录的自增长值
2. 索引🚀
-
索引原理:
- 无索引查询慢的原因:全表扫描
- 使用索引快的原因:形成一个索引的数据结构,比如二叉树
-
索引的代价:
- 对磁盘的占用
- 对 dml (update delete insert) 语句的效率影响(但是项目中 90% 都是select)
-
索引类型:
-
主键索引,主键自动地为主索引 (类型 primary key)
-
唯一索引 (unique)
-
普通索引 (index)
-
全文索引 (FULLTEXT) 【适用于 MYISAM]
开发中考虑使用:全文索引Solr 和ElasticSearch (ES)
-
-
语法
-- 查询表是否有索引 SHOW INDEXES FROM t25 -- 添加唯一索引1 CREATE UNIQUE INDEX id_index ON t25(id); -- 添加普通索引方式 1 CREATE INDEX id_index ON t25 (id) -- 添加普通索引地方式2 ALTER TABLE t25 ADD INDEX id_index (id) -- 创建表后添加主键索引 -- 不需要主键索引名,因为主键只有一个 ALTER TABLE t26 ADD PRIMARY KEY (id) -- 删除索引 DROP INDEX id_index ON t25 -- 删除主键索引 ALTER TABLE t26 DROP PRIMARY KEY -- 修改索引 , 先删除,在添加新的索引 -- 查询索引 -- 1. 方式 SHOW INDEX FROM t25 -- 2. 方式 SHOW INDEXES FROM t25 -- 3. SHOW KEYS FROM t25 -- 4 方式 DESC t25
索引总结:
哪些列适合使用索引
- 较频繁的作为查询条件字段应该创建索引
- 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
- 更新非常频繁的字段不适合创建索引
- 不会出现在 where 子句中字段不该创建索引
事务
(transaction)
-
**介绍:**用于保证数据一致性,它由一组相关的 dml 语句组成,该组的dml 语句要么全部成功,要么全部失败。如:转账
-
事务和锁:🔒 执行事务操作时(dml语句),mysql 会在表上加锁,防止其他用户修改表数据
-
基本操作
start transaction -- 开始一个事务 类比git init savepoint 保存点名 -- 设置保存点 git commit rollback to 保存点名 -- 回退事务 git reset --hard 版本号 rollback -- 回退全部事务 commit -- 提交事务,所有操作生效,不能回退
-
事务 细节
- 如果不开始事务,默认情况下, dml 操作时自动提交的,不能回滚
- 如果开始一个事务,你没有创建保存点,你可以执行 rollback,默认就是回退到你事务开始的状态
- 你也可以再这个事务中(还没 commit),创建多个保存带你。 比如savepoint aaa, 执行 dml; savepoint bbb。
- 你可以在事务没有提交前前,选择回退到哪个保存点
- mysql 的事务机制需要 innodb 的存储引擎
- 开始一个事务 start transaction, set autocommit = off
隔离
-
事务隔离级别: 事务与事务 之间的隔离程度
-
四种隔离级别
mysql隔离级别(4种) 脏读 不可重复读 幻读 加锁读 读未提交(Read uncommitted) V V V 不加锁 读已提交(Read committed) ❌ V V 不加锁 可重复读(Repeatable read) ❌ ❌ ❌ 不加锁 可串行化(Serializable) [演示重开客户端] ❌ ❌ ❌ 加锁 说明:V 表示可能出现 ❌代表不会出现
-
个人对四种隔离级别的浅理解
Read Uncommitted : 其他连接还没 committed 的内容都被读到了,换句话说就是受别人任何实时 DML 操作的影响
Read committed: 其他连接 ommitted 后的内容会被读到,也就是会受到别人 committed 的影响
Repeatable read: 可重复读的意思是,我从读的那个时刻开始,读的内容就锁定了,不受其他人操作的影响,所以可以重复地阅读(同一个)内容
Serializable: 加锁,线程安全
-
设置隔离级别
-
查看当前会话隔离级别
select @@tx_isolation;
-
查看系统当前隔离级别
select @@global.tx_isolation;
-
设置当前会话隔离级别
set session transaction isolation level repeatable read;
-
设置系统当前隔离级别
set global transaction isolation level repeatable read;
-
mysql默认的事务隔离级别是 repeatable read , 一般情况剩下,没有特殊要求,没有必要修改(因为该级别的隔离可以慢阻肺大部分项目的需求)
-
修改mysql 默认的隔离了级别
全局修改,修改 my.ini 配置文件,在最后加上
# 可选参数有 Read-Uncommitted , Read-Committed, Repeatable-Read, Serializable.
[mysql]
transaction-isolation = Repeatable-Read
-
实例
创建员工表,并向表中添加一条或多条记录
– 员工表 emp 的上增加一个 image 列,varchar 类型(要求在 resume 后面)。
– 修改 job 列,使其长度为 60。
– 删除 sex 列。
– 表名改为 employee。
– 修改表的字符集为 utf8
– 列名 name 修改为 user_name
错误的习惯和想法
-
表和数的区别
错误:
SELECT * FROM emp, tmp WHERE sal > (SELECT AVG(sal) FROM emp GROUP BY deptno)tmp AND emp.deptno = tmp.deptno
正确
SELECT * FROM emp,(SELECT deptno, AVG(sal) as avg_sal FROM emp GROUP BY deptno)tmp WHERE sal > avg_sal AND emp.deptno = tmp.deptno
总结
不能直接比较一个列名和一个临时表(select 返回的是一个表,虽然只有一列) 应该是比较一个列名 和 临时表的某列的指标值
后加上
\# 可选参数有 Read-Uncommitted , Read-Committed, Repeatable-Read, Serializable.
[mysql]
transaction-isolation = Repeatable-Read
实例
创建员工表,并向表中添加一条或多条记录
– 员工表 emp 的上增加一个 image 列,varchar 类型(要求在 resume 后面)。
– 修改 job 列,使其长度为 60。
– 删除 sex 列。
– 表名改为 employee。
– 修改表的字符集为 utf8
– 列名 name 修改为 user_name
错误的习惯和想法
-
表和数的区别
错误:
SELECT * FROM emp, tmp WHERE sal > (SELECT AVG(sal) FROM emp GROUP BY deptno)tmp AND emp.deptno = tmp.deptno
正确
SELECT * FROM emp,(SELECT deptno, AVG(sal) as avg_sal FROM emp GROUP BY deptno)tmp WHERE sal > avg_sal AND emp.deptno = tmp.deptno
总结
不能直接比较一个列名和一个临时表(select 返回的是一个表,虽然只有一列) 应该是比较一个列名 和 临时表的某列的指标值