呈: MySQL笔记_MySQL的小试
多张表联合查询,连接方式: 1. 内连接:等值连接、非等值连接、自连接。2. 外连接:左(外)连接、右(外)连接、全连接。
笛卡尔积:若两张表进行连接查询 无过滤条件 则 条数 为 两表条数乘积
找出 员工的部门名称
mysql> select e.ename,d.dname from emp e ,dept d;
-- 上条 更好 且 需要起 别名 易于 分别 且效率更高 可读性好
mysql> select ename,dname from emp,dept;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | ACCOUNTING |
| SMITH | RESEARCH |
| SMITH | SALES |
| SMITH | OPERATIONS |
| TURNER | SALES |
| TURNER | OPERATIONS |
| ADAMS | ACCOUNTING |
| ADAMS | RESEARCH |
| ADAMS | SALES |
| ADAMS | OPERATIONS |
...
| MILLER | SALES |
| MILLER | OPERATIONS |
+--------+------------+
56 rows in set (0.01 sec) -- 56 = 14 * 4
ps:避免 笛卡尔积
现象,同时不会减少记录的匹配次数,因而可以用来where
,having
加条件。
mysql> select e.ename,d.dname
-> from emp e , dept d
-> where
-> e.deptno = d.deptno;//92语法 不用
+--------+------------+
| ename | dname |
+--------+------------+
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
+--------+------------+
14 rows in set (0.01 sec)
内连接 --> 等值连接
条件是 等量关系 则可以分离条件
select e.ename, d.dname
from emp e
(inner)join dept d --inner 可以省略 带上更清晰
on e.deptno = d.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
+--------+------------+
14 rows in set (0.00 sec)
语法
select
e.ename,d.dname
from
emp e
join
dept d
on
连接条件
where
过滤条件
select e.ename,e.sal,s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal;
+--------+---------+-------+
| ename | sal | grade |
+--------+---------+-------+
| SMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
+--------+---------+-------+
14 rows in set (0.00 sec)
eg
. 找到每个员工 的上级领导(13条记录 忽略NULL)
select a.ename,b.ename
from emp a
join emp b
on a.mgr = b.empno;
+--------+-------+
| ename | ename |
+--------+-------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+-------+
13 rows in set (0.00 sec)
-- 将两张表看作一张表进行自连接 关键要找到合适的关系
-- 上表King无 上级
区别:与内链接 -能够匹配记录可以查询出来 就是内链接 且 无主辅之分
外连接:分主次 若副表 无主表数据 模拟NULL与之匹配
左连接 右连接 指的是主表的位置 可以相互替换 不忽略匹配不上的情况。
mysql> select a.ename,b.ename
-> from emp a
-> left(outer) join emp b
-> on a.mgr = b.empno;
-- or
mysql> select a.ename,b.ename
-> from emp b
-> right(outer) join emp a
-> on a.mgr = b.empno;
+--------+-------+
| ename | ename |
+--------+-------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+-------+
14 rows in set (0.00 sec)
-- 主表数据 无条件 全部查询出来
eg
: 找出哪个部门没有员工
mysql> select e.*[可以省略],d.*
-> from emp e
-> right join dept d
-> on e.deptno = d.deptno
-> where e.empno is NULL;
+-------+-------+------+------+----------+------+------+--
|EMPNO|ENAME|JOB|MGR| HIREDATE|SAL|COMM|DEPTNO|DEPTNO|
+-------+-------+------+------+----------+------+------+--
|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|40|OPERATIONS|
+-------+-------+------+------+----------+------+------+--
1 row in set (0.00 sec)
mysql> select d.*
-> from emp e
-> right join dept d
-> on e.deptno = d.deptno
-> where e.empno is NULL;
+--------+------------+--------+
| DEPTNO | DNAME | LOC |
+--------+------------+--------+
| 40 | OPERATIONS | BOSTON |
+--------+------------+--------+
1 row in set (0.00 sec)
三张表 的 连接
eg
:找出 每一个员工的 部门名称 和 薪资等级
-- 找出 每一个员工的 部门名称 和 薪资等级
...
-- A
-- join B
-- join C
-- A 先 和B连接 结果在和 C连接
select e.ename,d.dname,s.grade,e1.ename as authorname
from emp e
join dept d
on e.deptno = d.deptno
join salgrade s
on e.sal between s.losal and s.hisal
left join emp e1
on e.mgr = e1.empno;
+--------+------------+-------+
| ename | dname | grade |
+--------+------------+-------+
| SMITH | RESEARCH | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCH | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCH | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCH | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCH | 4 |
| MILLER | ACCOUNTING | 2 |
+--------+------------+-------+
-- ----------------------------------------加领导名
+--------+------------+-------+------------+
| ename | dname | grade | authorname |
+--------+------------+-------+------------+
| SMITH | RESEARCH | 1 | FORD |
| ALLEN | SALES | 3 | BLAKE |
| WARD | SALES | 2 | BLAKE |
| JONES | RESEARCH | 4 | KING |
| MARTIN | SALES | 2 | BLAKE |
| BLAKE | SALES | 4 | KING |
| CLARK | ACCOUNTING | 4 | KING |
| SCOTT | RESEARCH | 4 | JONES |
| KING | ACCOUNTING | 5 | NULL |
| TURNER | SALES | 3 | BLAKE |
| ADAMS | RESEARCH | 1 | SCOTT |
| JAMES | SALES | 1 | BLAKE |
| FORD | RESEARCH | 4 | JONES |
| MILLER | ACCOUNTING | 2 | CLARK |
+--------+------------+-------+------------+
14 rows in set (0.00 sec)
from 后 嵌套子查询
eg
:找出每个部门 的 平均薪水的 薪资等级
1. 找出每个部门的 平均薪水 (按照部门标号 分组 求 平均薪资)
select deptno,avg(sal) from emp group by deptno;
+--------+-------------+
| deptno | avg(sal) |
+--------+-------------+
| 10 | 2916.666667 |
| 20 | 2175.000000 |
| 30 | 1566.666667 |
+--------+-------------+
mysql> select t.*,s.grade
-> from (select deptno,avg(sal) as avgsal from emp group by deptno) t
-> join salgrade s
-> on t.avgsal between s.losal and hisal;
+--------+-------------+-------+
| deptno | avgsal | grade |
+--------+-------------+-------+
| 30 | 1566.666667 | 3 |
| 10 | 2916.666667 | 4 |
| 20 | 2175.000000 | 4 |
+--------+-------------+-------+
找出每个部门 平均的薪水等级
mysql> select e.deptno,avg(s.grade)
> from emp e
> join salgrade s
> on e.sal between s.losal and s.hisal
> group by e.deptno;
在 select 后 嵌套 子查询
select e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname
from emp e;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
union 可以将 查询结果集 相加
-- 找出 工作岗位是 salesman 和 manager 的员工
-- 第一种 or
mysql> select ename,job
-> from emp
-> where job = 'MANAGER' or job = 'SALESMAN';
-- 第二种 in
mysql> select ename,job
-> from emp
-> where job in('MANAGER','SALESMAN');
-- 第三种 union
mysql> select ename,job from emp where job = 'MANAGER'
-> union
-> select ename,job from emp where job = 'SALESMAN';
+--------+----------+
| ename | job |
+--------+----------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)
往往用于分页或排序查询来限制结果的显示方式
其中:
MySQL特有limit 查询 ,Oracle 有类似机制
rownum
limit 只取结果集中的 部分数据
limit 命令格式 :limit startIndex,length
ps
:起始值 startIndex(从零开始,可以不写) 长度length
- limit 最后执行
mysql> select ename,sal from emp order by sal desc limit 0,5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.01 sec)
eg
:找出4-9名工资排名
mysql> select ename,sal
-> from emp
-> order by sal desc
-> limit 3,6;
+--------+---------+
| ename | sal |
+--------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
+--------+---------+
6 rows in set (0.00 sec)
-- 通用 翻页 每页显示 pageSize条记录
-- 第 pageNo 页 (PageNo - 1) *pageNo = pageSize
与 Java 数据类型 对应理解记忆, 分别有 int、 bigint 、long;float 、double; char、varchar(
类似Java StringBuilder构造的字符串
)、date(from java.sql.Date);BLOB
二进制大对象(存储图片、视频 等流媒体信息) Binary Large Object;CLOB
字符大对象 存储较大文本 可以存储 4G 字符串 Character Large Object。eg. id(int) name(varchar) playtime(date/char) seal(BLOB) - IO流 history(CLOB)
char 效率高 不用判断 长度, char(6) 少补 多错 varchar(6) 智能分配
char 字段数据长度 是定长的 eg. 性别、生日
varchareg.
简介 姓名
-- 语法
> create table 表名(
字段名:数据类型,
字段名:数据类型,
字段名:数据类型,
字段名:数据类型,
...
);
-- 一般 数据库 创建表格时 建议 以 t_/tbl_
-- t_movie 命名
eg.
建立一个 拥有 “学号 姓名 性别 班级编号 生日” 的学生表格 -- 学号 姓名 性别 班级编号 生日
create table t_stu(
no bigint,
name varchar(255),
sex char(1),
classno varchar(255),
birth char(10)
);
Query OK, 0 rows affected (0.01 sec)
mysql> desc t_stu;
+---------+--------------+------+-----+-------+
| Field | Type| NULL | Key | Default | Extra |
+---------+--------------+------+-----+-------+
| no | bigint(20) | YES | | NULL | |
| name | varchar(255) | YES | | NULL| |
| sex | char(1) | YES | | NULL | |
| classno | varchar(255) | YES | | NULL| |
| birth | char(10) | YES | | NULL | |
+---------+--------------+------+-----+-------+
5 rows in set (0.00 sec)
-- 语法:
insert into 表名(
字段名,
字段名,
字段名,
)
values
(
val1,
val2,
val3,
) ;
-- ps :值和字段的数量要相同 且 数据类型要对应
插入方式,所有字段都赋值,或只给单个字段赋值。
insert into t_stu(
no,name,sex,classno,birth
)values(
1,'Zhangsan','f','gaosan1ban','1980-10-23'
);
-- 插入 一个字段 其他值 自动 赋值NULL 且 顺序可变
insert into t_student(name)values('Zhangsan');
Query OK, 1 row affected (0.01 sec)
drop table if exists t_stu;
create table t_student(
no bigint,
name varchar(255),
sex char(1) default 1,//指定默认值
classno varchar(255),
birth char(10)
)
当 insert 执行 一次 表中新产生一行 忽略NULL 且 不能再用insert 插入 只能用 update 更新
若按顺序 插入 前方 字段 默认 按 插入 顺序 和 数量 执行
ps.如果没有条件 则 全表更新
-- 语法格式:
update 表名 set
字段1=值1,
字段2=值2,
where conditon ;
-- 更新示例
-- 插入单行数据
insert into t_student values(
10,
'Zhangsan',
'gaoshan',
);
-- 插入多行数据
insert into t_student values(
20,
'Lisi',
'gaoshan',
),(
30,
'Wangwu',
'gaoshan',
);
update dept1 set loc = 'SHANGHAI',dname = 'RENSHIBU' where deptno = 10;
mysql> update dept1 set loc = 'x',dname = 'y';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from dept1;
+--------+-------+------+
| DEPTNO | DNAME | LOC |
+--------+-------+------+
| 10 | y | x |
| 20 | y | x |
| 30 | y | x |
+--------+-------+------+
4 rows in set (0.00 sec)
表的复制
create table 表名 as dql 语句;
create table emp1 as select ename,sal from emp;
-- 将 查询结果 赋作 新表
create table emp1 as select* from emp;
-- 将 查询结果 插入 一张表
-- 删除 可以 回滚 rollback
mysql>delete from table0 where conditions
/*if no condition delete all data*/
-- 截断 不可回滚
mysql> truncate table emp1;
Query OK, 0 rows affected (0.01 sec)
CRUD ---> R --> create retrieve update delete
非空约束(not NULL) 确保数据 合法、有效、完整性
唯一性约束(unique) 用户名 方便管理 不能重复
主键约束(primary key) : 不能为NULL 且不能 重复(PK)
外键约束(foriegn key)(FK)
检查约束(check) : Oracle 支持 check 约束 mysql 不支持该约束
drop table if exists t_user;
create table t_user(
id int,
username varchar(255) not NULL,
password varchar(255) not NULL,
);
insert into t_user(id,password) values(1,'123');
1364 ---> 缺 默认值
唯一 约 束 修饰 的 字段具有唯一性 不能重复 但 可以为NULL
drop table if exists t_user;
create table t_user(
id int,
username varchar(255) unique -- 列级约束
);
insert into t_user values(1,'Zhangsan');
insert into t_user values(2,'Zhangsan');
同时加 unique
drop table if exists t_user;
create table t_user(
id int,
usercode varchar(255),
username varchar(255),
unique(usercode,username) -- 加一个约束 表级约束
);
insert into t_user values(1,'111','Zhangsan');
insert into t_user values(2,'111','Lisi');
insert into t_user values(3,'222','Zhangsan');
select * from t_user;
mysql> select * from t_user;
+------+----------+----------+
| id | usercode | username |
+------+----------+----------+
| 1 | 111 | Zhangsan |
| 2 | 111 | Lisi |
| 3 | 222 | Zhangsan |
+------+----------+----------+
3 rows in set (0.00 sec)
------------------分别加约束----------------------
drop table if exists t_user;
create table t_user(
id int,
usercode varchar(255) unique,
username varchar(255) unique
);
insert into t_user values(1,'111','Zhangsan');
insert into t_user values(2,'111','Lisi');
drop table if exists t_user;
create table t_user(
id int primary key,
username varchar(255)
-- primary key(id)
);
MySQL的探索还在路上,加油!!