使用null和not null:
使用null的时候:
create table t1(
-> id int auto_increment primary key,
-> name varchar(32),
-> email varchar(32)
-> )charset=utf8;
insert into t1(email) values ('xx');
select * from t1;
select * from t1 where name='';*******
select * from t1 where name is null;*******
使用not null的时候
create table t2(
-> id int auto_increment primary key,
-> name varchar(32) not null default '',
-> email varchar(32) not null default ''
-> )charset=utf8;
insert into t2 (email) values ('xxx');
select * from t2;
select * from t2 where name = '';
1、单表操作(****)
分组
group by
分组指的是:将所有记录按照某个相同字段进行归类,比如针对员工信息表的职位分组,或者按照性别进行分组等
聚合函数:max(字段名),min(字段名),count(字段名),sum(字段名),avg(字段名)
用法:select 聚合函数,选取的字段 from 表 group by 分组的字段名;
group by:是分组的关键词
group by必须和聚合函数 如:(count)出现
where 条件语句和group by分组语句的先后顺序:
where>group by >having(****)
例:以性别为例,进行分组,统计一下男生和女生的人数是多少?
select count(id),gender from 表名 group by gender;
selectgender,count(id) as total from 表名 group by gender;
字段名 as 新字段名 as可以给旧字段起新字段别名
对部门进行分组,求出每个部门年龄最大的那个人?
select depart_id,max(age) from 表名 group by depart_id;
having
表示对group by之后的数据,进行再一次的筛选
select depart_id,avg(age) from 表名 group by depart_id;
select depart_id,avg(age) from 表名 group by depart_id having avg(age)>35;
where条件语句和group by 分组语句的先后顺序
where > group by >having(******)
升序 降序
order by
order by 字段名 asc (升序)desc(降序)
如果对多个字段进行排序
比如:
age desc,id asc
表示:先对age进行降序,如果age有相同的行,则对id进行升序
select * from 表名 order by age desc,id asc;
limit
分页
limit offset,size
offset:行数据索引
size:取多少条数据
select * from 表名 limit 0,10;
select * from 表名 limit 10,10;#(从第10行开始往下取10行)
总结:(********)
使用的顺序:
select * from 表名 where 条件 group by 条件 having 条件 order by 条件 limit 条件:
where > group by >having >order by >limit
内连接:
内连接是比较常用的连接方式,它取的值是两个表的交集;
关键字:inner join 可简写成join
select A.*,B.dept_code,B.dept_name from tb_user A join tb_dept B on A.dept_id = B.id;
左连接:
左连接是我们最常用的一种连接;关键字:left outer join 可简写成letf join
它是以A为主表,B为副表关联查询,查询结果以A表数据为基准;
select * from tb_user A left join tb_dept B on A.dept_id = B.id;
如果想要筛选A表中的数据但又不存在B的关联数据,可以这样写(常用于查询脏数据);
select *from tb_user A left join tb_dept B on A.dept_id = B.id where B.id is null;
右连接
右连接我们不太常用,因为它可以被左连接取代,只需要把左连接的两个关联表替换一下即可实现右连接的效果
它是以B为主表,A为副表关联查询,查询结果以B表数据为基准;关键字:right outer join可简写成right jion
select*from tb_user A right join tb_dept B on A.dept_id = B.id;
其他
还有一种连接方式也很常用[逗号分隔表],关联条件需写在where中
有关联条件时,其查询结果与内连接相同;无关联条件时,其结果为两个表的笛卡尔积。
select * from tb_user A,tb_dept B where A.dept_id = B.id;
拓展
笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积,
又称直积,表示为X × Y,第一个对象是X的成员 第二个对象是Y的所有可能有序对的其中一个成员
拓展
表关联中的where和on的区别:
on:针对关联表进行条件筛选,不会影响结果集的数量和主表数据
where:针对结果集进行条件筛选,会影响结果集的数量
2、多表操作(**********)
外键
使用的原因:
a.减少占用的空间
b.只需要修改,只需要修改表中一条记录,其余的表中的数据就会相应的修改(级联)
一对多:
使用方法:
constraint 外键名 foreign key (被约束的字段)reference 约束的表(约束的字段)
create table department(
id int auto_increment primary key,
name varchar(32) not null default ''
)charset utf8;
insert into department(name) values ('研发部');
insert into department(name) values ('运维部');
insert into department(name) values ('前台部');
insert into department(name) values ('小卖部');
create table userinfo(
id int auto_increment primary key,
name varchar(32) not null default '',
depart_id int not null default 1,
constraint fk_user_depart foreign key (depart_id) references department(id)
)charset utf8;
insert into userinfo(name,depart_id)values ('zekai',1);
insert into userinfo(name,depart_id)values ('xxx',2);
insert into userinfo(name,depart_id)values ('zekai1',3);
insert into userinfo(name,depart_id)values ('zekai2',4);
insert into userinfo(name,depart_id)values ('zekai3',1);
insert into userinfo(name,depart_id)values ('zekai4',2);
insert into userinfo(name,depart_id)values ('zekai5',5);#(超出字段规定会报错)
报错信息:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`kk`.`userinfo`,
CONSTRAINT `fk_user_depart` FOREIGN KEY (`depart_id`) REFERENCES `department` (`id`))
多对多
create table boy(
id int auto_increment primary key,
bname varchar(32) not null default ''
)charset utf8;
insert into boy(bname) values ('zhnagsan'),('lisi'),('zhaowu');
create table girl(
id int auto_increment primary key,
gname varchar(32) not null default ''
)charset utf8;
insert into girl (gname) values ('cuihua'),('gangdan'),('jianguo');
create table boy2girl(
id int auto_increment primary key,
bid int not null default 1,
gid int not null default 1,
constraint fk_boy2girl_boy foreign key (bid) references boy(id),
constraint fk_boy2girl_girl foreign key (gid) references girl(id)
)charset utf8;
insert into boy2girl (bid,gid)values(1,1),(2,3),(3,3),(2,2);
select * from boy left join boy2girl on boy.id=boy2girl.bid left join girl on girl.id=boy2girl.gid;
select bname,gname from boy left join boy2girl on boy.id = boy2girl.bid left join girl on girl.id=boy2girl.gid;
select bname,gname from boy left join boy2girl on boy.id = boy2girl.bid left join girl on girl.id=boy2girl.gid where bname='zhangsan';
一对一
user:
id name age salary
1 zekai 18 5000
2 zs 23 6000
3 xxxx 19 3000
由于salary是比较敏感的字段,因此我们需要将此字段独拆出来,变成一张独立的表
private:
id salary uid (外键+unique)
1 5000 1
2 6000 2
3 3000 3
create table priv(
id int auto_increment primary key,
salary int not null default 0,
uid int not null default 1,
constraint fk_priv_user foreign key (uid) references user(id),
unique(uid)
)charset utf8;
insert into priv(salary,uid) values (2000,1);
insert into priv(salary,uid) values (2800,2);
insert into priv(salary,uid) values (3000,3);
多表联查
1、左连接(left join ...on)
select * from department;
select * from userinfo;
select userinfo.name as uname, department.name as dname from userinfo left join department on depart_id = department.id;
2、内部连接(inner join)
select * from department inner join userinfo on department.id=userinfo.depart_id;