day35

使用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;
原文地址:https://www.cnblogs.com/gfhh/p/11767707.html