- 常用的数据类型
(1) char: 字符
(2) varchar: 字符串
(3) int: 整数
(4) float: 单精度(精度有一定的范围)
(5) double: 双精度
(6) date: 日期 年月日
(7) timestamp: 年月日, 时分秒
注意
(1) char与varchar区别
如果将abc赋予char(10) ==> abcxxxxxxx
如果将abc赋予vchar(10) ==> abc
- SQL种类
(1)DML(增删改查): insert、update、delete、select
(2)DDL(创建db、创建table): create databases/drop databases
- 创建table
(1) create table henrydb.henrydata(
id int,
name varchar(100),
age int,
//创建时间
createtime timestamp,
//创建人
createuser varchar(100),
//更新时间
updatetime timestamp,
// 更新人
updateuser varchar(100)
);
在DBeaver中显示的
CREATE TABLE `henrydata` (
`id` int(11) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
//默认是当前时间,当做update更新时会更新当前的时间
`createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`createuser` varchar(100) DEFAULT NULL,
`updatetime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updateuser` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
注意:
(1) 表名称字段名称尽量表达值的意思
(2) 新建字段与之前字段形式保持一致
- insert数据
(1) insert into henrydata(id, name, age) values(1, 'henry', 18);
- select
(1) select * from henrydata;
- update
(1) update henrydata set age=20 where id=1;
- delete
(1) delete from henrydata where id=1
注意: 确认delete后面是否有where语句
- 改进版建表
/*生产上建表后面都加上prod*/
create table henrydb.henrydata_prod(
/*自增长, 主键约束*/
id int auto_increment primary key,
name varchar(100),
age int,
/*默认值约束 default*/
create_time timestamp default current_timestamp,
create_user varchar(100),
/*on update 只要更新mysql就会自动更新*/
update_time timestamp default current_timestamp on update current_timestamp,
update_user varchar(100)
/*设置默认字符集*/
)default charset=utf8;
注: 第一行与后四行是固定的
- 在prod上增删改查数据
/*不需要主动输入id,因为id自增长,mysql会帮我们设置*/
insert into henrydb.henrydata_prod(name, age) values('henry', 20);
select id, name, age from henrydata_prod;
- insert 的两种形式
(1) 指定字段
insert into henrydb.henrydata_prod(name, age) values('henry', 20);
(2) 不指定字段
insert into henrydb.henrydata_prod values(2, 'henry','2018-11-19 15:00:00', 'h', '2018-11-10 16:00:00', 'h');
常见错误
(1)Column count doesn't match value count at row 1
insert into henrydb.henrydata_prod values(2,'2018-11-19 15:00:00', 'h', '2018-11-10 16:00:00', 'h');
(2) Column count does not match value count at row 1
insert into henrydb.henrydata_prod values(1, 'henry','2018-11-19 15:00:00', 'h', '2018-11-10 16:00:00', 'h');
因为id为1已经存在,id为主键,主键是唯一的
- 更新语句
(1) 将该表的age字段都设置为22
update henrydata_prod set age=22;
(2) update其age和address
/*修改多个字段用逗号分割*/
update henrydata_prod set age=25, address='zbc';
(3) 有条件更新(单个条件)
update henrydata_prod set age=25, address='zbc' where name='henry';
(4) 有条件更新(多个条件)
update henrydata_prod set address='abc' where name='henry' and age=21;
(5) 有条件更新或
update henrydata_prod set address='深圳' where name='henry' or age=25;
- 删除语句
(1) 删除全部数据
delete from henrydata_prod;
(2) 有条件删除
delete from henrydata_prod where age=19;
- 比较符号
> < = >= <= <>
- 模糊查询
like
示例: 查询名字中包含S的数据
select * from emp where ename like '%S%';
查询名字以S开头的数据
select * from emp where ename like 'S%';
查询名字以S结尾的数据
select * from emp where ename like '%S';
查询第二个字母是O的数据, 每个 "_"代表一个占位符
select * from emp where ename like '_O%';
15.排序
(1) 默认从小到大排序
select * from emp order by sal;
(2) 升序排列
select * from emp order by sal asc;
(3) 降序排列
select * from emp order by sal desc;
(4) 首先按照deptno进行升序排列,如果deptno相同的话,然后按照sal降序排序,
如果这两项都相同,按照第一列排序
注: 在生产中,大部分情况下都用where进行筛选
select * from emp order by deptno asc, sal desc;
- 限制多少行
限制两行,limit加在筛选之后
select * from emp order by deptno asc, sal desc limit 2;
17.聚合(group by)
select deptno, sum(sal) as salSum from emp group by deptno;
先对deptno进行分组,然后对job进行分组
注:
select deptno, job, sum(sal) as salSum from emp group by deptno;
(
在select中出现的字段如deptno和job,在group by也必须出现
字段顺序在group by中可以变化,先按按个进行分组不会导致错误,
但是 尽量还是与select的字段顺序保持一致
)
注意: group by 字段必须出现在 select 字段 (“工作中已经不止一次由此出错”)
- 聚合函数
(1) 聚合函数: sum, count, avg, max, min
select deptno, job from emp
where job = "SALESMAN"
group by deptno, job
having sun(sal) > 3000
order by sum(sal) desc
limit 3;
- having
select deptno, sum(sal) as salSum from emp
group by deptno having sun(sql) > 9000;
注: 对查询结果进行聚合,然后对聚合后的结果进行筛选
使用group by......having......
20 union
去除重复数据
select id, name from a
union
select id, address from b
不去除重复数据
select id, name from a
union all
select id, address from b
注意:
1. 查询的结果显示的字段名称由第一张表决定
2. 在生产中,避免使用select *, 使用select 想要查询的字段
3. 两张表对应位置的字段类型应保持一致
- 子表
各个部门各个岗位的薪水和, 并且薪水和大于3000
注: 子表必须要起别名
select
t.*
from
(
select
deptno, job, sum(sal) as sum_sal
from emp
group by deptno, job
) as t
where t.sum_sal > 3000
- join
inner join: 内连接或等值连接 (不经常使用)
left join: 左连接 (常用)
right join: 右连接
新建testa表
+------+--------+
| aid | aname |
+------+--------+
| 1 | henry1 |
| 2 | henry2 |
| 3 | henry3 |
| 4 | henry4 |
| 5 | henry5 |
+------+--------+
新建testb表
+------+--------+------+
| bid | bname | age |
+------+--------+------+
| 1 | henry1 | 15 |
| 2 | henry2 | 16 |
| 3 | henry3 | 17 |
| 4 | henry4 | 18 |
| 7 | henry7 | 19 |
| 8 | henry8 | 20 |
| 9 | henry9 | 21 |
+------+--------+------+
left join
select
a.aid, a.aname,
b.bid, b.bname
from
testa a left join testb b on a.aid = b.bid;
输出结果为
+------+--------+------+--------+
| aid | aname | bid | bname |
+------+--------+------+--------+
| 1 | henry1 | 1 | henry1 |
| 2 | henry2 | 2 | henry2 |
| 3 | henry3 | 3 | henry3 |
| 4 | henry4 | 4 | henry4 |
| 5 | henry5 | NULL | NULL |
+------+--------+------+--------+
which means
left join : 以左表数据为主, 左表的数据会全部显示出来,
但是右表的数据只显示能和左表匹配(on + 字段)上的,
如果坐标某一record有数据,右表没有,右表的字段就为null,如上表所示
注: right join与left join正好相反
inner join: 两张表匹配的数据行才显示
select
a.aid, a.aname,
b.bid, b.bname
from
testa a left join testb b on a.aid = b.bid;
select
a.aid, a.aname,
b.bid, b.bname
from
testa a left join testb b on a.aid = b.bid;
testa表
+------+--------+
| aid | aname |
+------+--------+
| 1 | henry1 |
| 2 | henry2 |
| 3 | henry3 |
| 4 | henry4 |
| 5 | henry5 |
+------+--------+
testb表
+------+---------+------+
| bid | bname | age |
+------+---------+------+
| 1 | henry11 | 15 |
| 2 | henry22 | 16 |
| 3 | henry3 | 17 |
| 4 | henry4 | 18 |
| 7 | henry7 | 19 |
| 8 | henry8 | 20 |
| 9 | henry9 | 21 |
+------+---------+------+
select
a.aid, a.aname,
b.bid, b.bname
from
testa a left join testb b
on
a.aid = b.bid and a.anane = b.bname;
上sql语句的结果为
+------+--------+------+--------+
| aid | aname | bid | bname |
+------+--------+------+--------+
| 3 | henry3 | 3 | henry3 |
| 4 | henry4 | 4 | henry4 |
| 1 | henry1 | NULL | NULL |
| 2 | henry2 | NULL | NULL |
| 5 | henry5 | NULL | NULL |
+------+--------+------+--------+
在上面sql语句中,只有3, 4符合条件,其他的testb都不符合条件,所以只有testa表的数据
多表join
eg. 查询员工的所属部门是什么?在什么地方?工资等级是什么?
select
empno, ename, e.deptno, dname, loc, (sal+comm) as total_sal, grade
from
emp e left join dept d on e.deptno = d.deptno
left join salgrade on (sal + comm) between losal and hisal;
查询结果为
+-------+--------+--------+------------+----------+-----------+-------+
| empno | ename | deptno | dname | loc | total_sal | grade |
+-------+--------+--------+------------+----------+-----------+-------+
| 7499 | ALLEN | 30 | SALES | CHICAGO | 1900.00 | 3 |
| 7521 | WARD | 30 | SALES | CHICAGO | 1750.00 | 3 |
| 7844 | TURNER | 30 | SALES | CHICAGO | 1500.00 | 3 |
| 7654 | MARTIN | 30 | SALES | CHICAGO | 2650.00 | 4 |
| 7782 | CLARK | 10 | ACCOUNTING | NEW YORK | NULL | NULL |
| 7839 | KING | 10 | ACCOUNTING | NEW YORK | NULL | NULL |
| 7934 | MILLER | 10 | ACCOUNTING | NEW YORK | NULL | NULL |
| 7369 | SMITH | 20 | RESEARCH | DALLAS | NULL | NULL |
| 7566 | JONES | 20 | RESEARCH | DALLAS | NULL | NULL |
| 7788 | SCOTT | 20 | RESEARCH | DALLAS | NULL | NULL |
| 7876 | ADAMS | 20 | RESEARCH | DALLAS | NULL | NULL |
| 7902 | FORD | 20 | RESEARCH | DALLAS | NULL | NULL |
| 7698 | BLAKE | 30 | SALES | CHICAGO | NULL | NULL |
| 7900 | JAMES | 30 | SALES | CHICAGO | NULL | NULL |
+-------+--------+--------+------------+----------+-----------+-------+
由于NULL + 任意数值结果还是NULL,所以需要对NULL进行处理
改进后sql语句
select
empno, ename, e.deptno, dname, loc, (sal+IFNULL(comm,0)) as total_sal, grade
from
emp e left join dept d on e.deptno = d.deptno
left join salgrade on (sal + IFNULL(comm,0)) between losal and hisal;
查询结果为
+-------+--------+--------+------------+----------+-----------+-------+
| empno | ename | deptno | dname | loc | total_sal | grade |
+-------+--------+--------+------------+----------+-----------+-------+
| 7369 | SMITH | 20 | RESEARCH | DALLAS | 800.00 | 1 |
| 7876 | ADAMS | 20 | RESEARCH | DALLAS | 1100.00 | 1 |
| 7900 | JAMES | 30 | SALES | CHICAGO | 950.00 | 1 |
| 7934 | MILLER | 10 | ACCOUNTING | NEW YORK | 1300.00 | 2 |
| 7499 | ALLEN | 30 | SALES | CHICAGO | 1900.00 | 3 |
| 7521 | WARD | 30 | SALES | CHICAGO | 1750.00 | 3 |
| 7844 | TURNER | 30 | SALES | CHICAGO | 1500.00 | 3 |
| 7782 | CLARK | 10 | ACCOUNTING | NEW YORK | 2450.00 | 4 |
| 7566 | JONES | 20 | RESEARCH | DALLAS | 2975.00 | 4 |
| 7788 | SCOTT | 20 | RESEARCH | DALLAS | 3000.00 | 4 |
| 7902 | FORD | 20 | RESEARCH | DALLAS | 3000.00 | 4 |
| 7654 | MARTIN | 30 | SALES | CHICAGO | 2650.00 | 4 |
| 7698 | BLAKE | 30 | SALES | CHICAGO | 2850.00 | 4 |
| 7839 | KING | 10 | ACCOUNTING | NEW YORK | 5000.00 | 5 |
+-------+--------+--------+------------+----------+-----------+-------+
注:
1. join可以出现多次
2. on后面语句也可以加 >, <, <>, between
3. 由于NULL + 数值还是NULL, 需要IFNULL()函数对其进行处理
- 简单举例
求出各个/每部门的薪水和
注意: 看见各个/每就用group by
select
deptno, sun(sal)
from emp
group by deptno
各个部门各个岗位的薪水和
select
deptno, job, sun(sal)
from emp
group by deptno, job