Mysql问题汇总&学习记录3:表之间的关系以及记录的增删改查

MySQL学习记录3

表关系:

1、多对一

2、多对多

3、一对多

1、多对一

建立关联表和被关联表即可,foreign key

create table press(
    id int primary key auto_increment,
    name varchar(20)
);

create table book(
    id int primary key auto_increment,
    name varchar(20),
    press_id int not null,
    foreign key(press_id) references press(id)
    on delete cascade
    on update cascade
);

insert into press(name) values
('出版社1'),
('出版社2'),
('出版社3');

insert into book(name,press_id) values
('饺子',1),
('包子',2),
('馄饨',2),
('玉米',3),
('馒头',3);
2、多对多

需要建立中间表,来建立两表之间的关系

#先建立book表(1中已建立),author表如下
create table author(
    id int primary key auto_increment,
    name varchar(20)
);

#建立两表格的关系
create table author2book(
    id int not null unique auto_increment,
    author_id int not null,
    book_id int not null,
    constraint fk_authon foreign key(author_id) references author(id)
    on delete cascade
    on update cascade,
    constraint fk_book foreign key(book_id) references book(id)
    on delete cascade
    on update cascade,
    primary key(author_id,book_id)
);

#插入author,id依次排开
insert into author(name) values('dumpling'),('corn');

#每个作者的代表作
dumpling:
饺子
包子
玉米
馄饨
馒头
corn:
玉米
馒头

insert into author2book(author_id,book_id) values
(1,6),(1,7),(1,8),(1,9),(1,10),(2,9),(2,10);

#查看对应关系,只需查看关联表即可。
3、一对一

foreign key + unique

create table customer(
    id int primary key auto_increment,
    name varchar(10) not null,
    qq varchar(10) not null,
    phone char(16) not null
);

create table student(
    id int primary key auto_increment,
    class_name varchar(20)not null,
    customer_id int unique,#该字段必须唯一
    foreign key (customer_id) references customer(id)#外键的字段必须保证unique
    on delete cascade
    on update cascade
);

insert into customer(name,qq,phone) values
('饺子','9218127214',19827191228),
('包子','9218123144',19241121238),
('汤圆','9218231145',11298319412);

insert into student(class_name,customer_id) values
('BB1班',1),
('AA2班',3);

记录的增删改查

插入数据insert:除了之前的values用法,还有一种:

insert into 表名(字段1,字段2,...,字段n)
select(字段1,字段2,...,字段n) From 表2
where...;

更新数据update

update 表名 set
	字段1 = 值1,
	字段2 = 值2,
	where condition;

#示例:更改密码
	update mysql.user SET password = password('123'),
	where user='root' and host = 'localhost';

**删除数据delete:**只删除指定位置的一定数据

delete from 表名
	where condition;
	
#示例
	delete from mysql.user
	where password='';

truncate table:删除table表中的所有记录

**查询数据select:**单表查询、多表查询

单表查询:

select distinct(去重) 字段1,字段2,字段3 from 库.表

​ where 条件

​ group by 分组条件

​ having 过滤

​ order by 排序字段

​ limit n;限制

查询数据

单表查询:
#简单查询:
select xxx,xx,xxx from xxx;
select * from xxx;

#避免重复
select distinct xx from xxx;#筛去重复项

#通过四则运算查询
select xxx*12 as xxxA from xxx;#可以直接将原数据*12的结果查出来(所得为虚拟表),xxxA为该新数据的表头名称

#定义显示格式
concat()#函数用于连接字符串
select concat('姓名:',name) as xxxB,concat('性别:',sex) as xxxC from xxx;#按照该格式查出name包含的数据,xxxB为标题;
concat_ws()#第一个参数为分隔符
select concat_ws(':',name,sex) as xxxD from xxx;
select concat(name,':',sex) from xxx;#与上一条相同,当数据多的时候使用concat_ws指定分隔符更好
where约束:

where字句中可以使用:

1、比较比较运算符:>< >= <= !=

2、between 80 and 100 值80到100之间

3、in(80,90,100) 值为80或90或100

4、like ‘xxx%’

5、逻辑运算符:在多个条件可以直接使用逻辑运算符 and or not

#单条件查询
select xxx from xxx where id>7;

#多条件查询
select xxx from xxx where id>7 and age<10;

#between and

#关键词is null(判断某个字段是否为null不能用等号,需要用is)

#关键词in
select xxx from xxx where age in(28,45,22);#可直接取出这三个age的数据

#关键词like模糊查询(模糊匹配)
#eg:比如姓李的开头:
select * from xxx where name like "李%";#%后面可以是任意字符
select * from xxx where name like "李__";#下划线可指定后面有几个字符

逻辑顺序:先from,再where,再select。

group by:分组

1、分组发生在where之后,是基于where之后得到的记录而进行的

2、分组:将所有记录按照某个相同字段进行归类,比如针对员工信息表职位分组,或者按照性别进行分组等。

3、取出每个数据类型的类别等。如最高工资,某部门员工数。

4、大前提:可按照任意字段分组,但分组完毕后,如gruop by post,只能查看post字段,如需查看组内信息,需借助聚合函数。

select * from xxx group by post;
set global sql_mode ="ONLY_FULL_GROUP_BY";#设置分组只能取分组的组名,即
select post from xxx group by post;

#聚合函数
max
min
avg#平均值
sum#和
count#数个数

#eg.每个职位有多少个员工
select post,count(id) as emp_count from employee group by post;

#分组之后,只能取分组的字段,以及每个组聚合结果
#没有group by则默认整体算作一组

group_concat(xxx)#可将xxx的所有数据提取出来eg:
select post,group_concat(name) from employee group by post;
having:过滤

1、执行优先级:where>group by>having>选字段

2、where中可以有任意字段,但不能有聚合函数

3、having可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数

order by:排序

原始排序方式,自然排序(1,2,…)

执行优先级在distinct之后(但在limit之前)

select * from employee order by age asc;#默认也为asc(升序)
select * from employee order by age desc;#降序
select * from employee order by age asc,id desc;#先按照age升序,如果一样则按照id降序
limit:限制显示条数
select * from employee limit 3;#选择出前三条来显示
select * from employee limit 0,5;#从0开始往后数五条
select * from employee limit 5,5;#从5开始往后再数五条
#该方法效率不太高

总结:语法顺序:

select distinct(去重) 字段1,字段2,字段3 from 库.表 
where 条件
group by 分组条件
having 过滤
order by 排序字段
limit n;限制

执行顺序:

def from(db,table):

def where(conditon,f):

def group(lines):
	
def having(group_res):

def distinct(having_res):

def order(distinct_res):

def limit(order_res):

def select():
	#按顺序执行以上函数。
补充:正则查询

正则表达式:

select * from xxx where name like 'jin%';#jin开头的字段
select * from xxx where name regexp'^jin';#

连表操作

内连接、左连接、右连接、全外连接

#引入,加入逻辑关联(内连接)
select * from employee,department where employee.dep_id = department.id;

内连接:只取两张表的共同部分

select * from xxx1 inner join department on xxx1.id1 = xxx2.id2;

左连接:在内连接的基础上保留左表的记录

select * from xxx1 left join department on xxx1.id1 = xxx2.id2;

右连接:在内连接的基础上保留右表的记录

select * from xxx1 right join department on xxx1.id1 = xxx2.id2;

全外连接:在内连接的基础上保留左右两表没有对应关系的记录

select * from xxx1 full join department on xxx1.id1 = xxx2.id2;
#这个不行的话可以使用联合左右连接的操作,union
select * from xxx1 right join department on xxx1.id1 = xxx2.id2
union
select * from xxx1 left join department on xxx1.id1 = xxx2.id2;

select语句关键关键字的定义顺序总结

select语句关键字的定义顺序与逻辑顺序(序号为逻辑顺序)
(7)select 
(8)distinct