php笛卡尔积和子查询,三、单表、多表、子查询

一、单表查询的关键字

(一)where条件比较运算符:> < >= <= <> !=

between 80 and 100 :在80和100之间,闭区间,包含80和100

in(23,45,23):值是23或45或23

like'wick%':以wick开头,%代表任意多字符,_标识一个字符

逻辑运算符:and or not

(二)分组group by分组是指所有记录按照某个相同字段进行归类,比如针对员工信息表的职位分组

分组必须和聚合函数联用,优先级低于where

(1)聚合函数

聚合函数聚合的是组的内容,如果没有分组,则默认一组count:计数

count内的字段的类型可以为任意类型

sum:求和

sum内的字段的类型必须为数字类型

max:最大值

min:最小值

avg:平均值select 聚合函数,分组的字段 from 表名 group by 分组的字段

# 聚合函数和分组字段的顺序随便

# 例子

# 统计男生和女生的人数(以性别分组)

select count(id),gender from employee group by gender;

# 统计每个部门中最大的年龄(以部门分组)

select depart_id,max(age) from employee group by depart_id;

(三)二次筛选having

用来对group by分组之后的数据再进再次筛选,相当于where,优先级低于group byselect depart_id,avg(age) from employee group by depart_id having avg(age) >35;

(四)升降序order by

根据字段名排序,可以对多个字段进行排序asc :升序,不写的话默认升序

desc:降序# age desc, id asc;

# 表示: 先对age进行降序, 如果age有相同的行, 则对id进行升序

# 例子

select * from employee order by age desc, id desc

(五)limit

优先级低于order bylimit 行索引 数据显示的函数

#例子

# 标识从行索引为0开始,总共显示10条数据

select * from employee limit 0 10;

(六)关键字的执行优先级

从上到下优先级递减:from

where

group by

having

select

distinct

order by

limit

二、多表操作

(一)多表创建

(1)约束条件:foreign key和unique

创建表时,一张表关联另一张表,约束其id在其范围内作用无需重复存储,减少占用的空间

需要修改时,只需要修改对应表中的数据

(2)一对多

一个表中的id可以被另一个表多次调用,比如员工信息表和部门表,可以有多个员工是同一个部门# 语法

constraint 外键名 foreign key (被约束的字段) references 约束的表 (约束的字段)

# 例子

# 一张部门表,一张员工信息表,用id表示部门,约束该id必须在部门表的范围内

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 ('小卖部');

# 约束user_info中的字段depart_id只能是department中id中的一个

create table user_info(

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 ('zekai4', 5);

(3)多对多

一个表可以多次调用两外两个表中的id,从而达到节省空间,和便于管理的目的# 创建表boy,并插入数据

create table boy (

id int auto_increment primary key,

bname varchar(32) not null default ''

)charset utf8;

insert into boy (bname) values ('zhangsan'),('lisi'),('zhaoliu');

# 创建表girl,并入数据

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');

# 创建表boytogirl,外键为表boy和表gilr

create table boytogilr(

id int auto_increment primary key,

bid int not null default 1,

gid int not null default 1,

constraint fk_boyyogilr_boy foreign key (bid) references boy(id)),

constraint fk_boyyogilr_gilr foreign key (gid) references girl(id)

)charset utf8;

insert into boy2girl (bid, gid) values (1,1),(1,2),(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;

(4)一对一一个表中的id只能被另一个表调用一次,比如员工信息表和薪水表,一个员工只能有一种薪水

约束条件unique:唯一约束,指定某列不能重复# 创建员工信息表

create table user (

id int auto_increment primary key,

name varchar(32)not null default ''

)charset utf8;

insert into user (name) values ('zhangsan'),('zekai'),('kkk');

# 创建薪水表

create table priv(

id int auto_increment primary key,

salary float 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);

insert into priv (salary, uid) values (6000, 1); # 为1的uid只能使用一次,因此会报错

(二)多表联查

(1)左连接left join

优先显示左表全部记录# 语法

select 表名1.字段1,表名2.字段2 from 表名1 left join 表名2 on 表名1.字段3 = 表名2.字段1;

# 例子

select userinfo.name,departmen .name from userinfo left join department on userinfo.depart_id = department.id;

(2)右连接right join

优先显示右表全部记录# 语法同最left join一样

# 例子

select userinfo.name,departmen .name from userinfo right join department on userinfo.depart_id = department.id;

(3)内连接inner join

只连接匹配的行,等同于where# 例子

select * from department inner join userinfo on department.id=userinfo.depart_id;

(4)交叉连接

不适用任何匹配条件,生成笛卡尔积select * from employee,department;

三、子查询(额外补充)

讲一个查询语句嵌套在另一个查询语句中

效率低,一般不适用in

比较运算符

exists:内层返回真假值,若返回Ture,外层语句查询,否则,不进行查询# in

select id,name from department

where id in (select dep_id from employee group by dep_id having avg(age) > 25);

# 比较运算符

select name,age from emp where age > (select avg(age) from emp);

# exists

select * from employee where exists (select id from department where id=200);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值