SQL

SQL

SQL Server

SQL server查询操作技巧大全:https://www.jb51.net/Special/595.htm

视频:https://www.bilibili.com/video/BV1ct411G78W?t=80&p=11

简单增删改

创建表格

专业表:major

​ mno(专业号)、mname(专业名)

学生表:stu

​ sno(学号)、sname(姓名)、age(年龄)、sex(性别)、 mno(专业号)

课程表:cou

​ cno(课程号)、cname(课程名)、ctime(学时)、ccredit(学分)

成绩表:sc

​ sno(学号)、cno(课程号)、grade(成绩)

create database stuinfo
--创建stuinfo数据库
----------------------------------------------------
use stuinfo
--打开stuinfo数据库
----------------------------------------------------
create table major(
	mno int primary key,
    --primary key:设置为主键
	mname varchar(30)
)
----------------------------------------------------
create table stu(
	sno varchar(13) primary key,
	sname varchar(30) not null,
	age int ,
	sex bit,
	mno int,
	foreign key(mno) references major(mno)       
    --foreign key:设置为外键,foreign key后面的mno指的是stu表中的mno字段
)
----------------------------------------------------
create table cou(
	cno varchar(13) primary key,
	cname varchar(30) not null,
	ctime int,
	ccredit decimal(5,2)
)
----------------------------------------------------
create table sc(
	cno varchar(13),
	sno varchar(13),
	grade decimal(5,2),
	primary key(cno,sno),
	foreign key(cno) references cou(cno),
	foreign key(sno) references stu(sno),
)
----------------------------------------------------

alter table sc add constraint fk_sc foreign key(cno) references cou(cno)
--表建成后,给sc表添加外键

添加数据

select * from major
insert into major(mno,mname) values(1,'计算机科学与技术');
insert into major(mno,mname) values(2,'软件工程');
insert into major(mno,mname) values(3,'网络工程');
insert into major(mno,mname) values(4,'智能科学与技术');
----------------------------------------------------
select * from stu
insert into stu values('2020001','小一',18,0,1);
insert into stu values('2020002','小二',18,1,1);
insert into stu values('2020003','小四',18,1,1);
insert into stu values('2020004','小五',18,1,1);
insert into stu values('2020005','小六',18,0,2);
insert into stu values('2020006','小七',18,1,2);
insert into stu values('2020007','小八',18,0,2);
insert into stu values('2020008','小九',18,1,2);
insert into stu values('2020009','小十',19,0,3);
insert into stu values('20200010','小十',20,0,3);
insert into stu values('20200011','小快',19,0,3);
insert into stu values('20200012','小冬',21,0,3);
insert into stu values('20200013','小宇',19,0,null);
insert into stu values('20200014','小点',19,0,4);
insert into stu values('20200015','彭杰',21,0,4);
insert into stu values('20200016','彭小杰',21,0,4);
----------------------------------------------------
select * from  cou
insert into cou values('20201','C语言',32,5);
insert into cou values('20202','C#',32,3);
insert into cou values('20203','数据结构',16,5);
insert into cou values('20204','大学英语1',32,3.5);
insert into cou values('20205','大学英语2',32,3.5);
insert into cou values('20206','大学英语3',32,3.5);
insert into cou values('20207','大学英语4',32,3.5);
----------------------------------------------------
select * from sc
insert into sc(sno,cno,grade) values('2020006','20201',null);
insert into sc(sno,cno,grade) values('2020005','20201',null);
insert into sc(sno,cno,grade) values('2020001','20201',90);
insert into sc(sno,cno,grade) values('2020002','20201',90);
insert into sc(sno,cno,grade) values('2020003','20201',90);
insert into sc(sno,cno,grade) values('2020004','20201',58);
insert into sc(sno,cno,grade) values('2020004','20202',98);
insert into sc(sno,cno,grade) values('2020004','20203',90);
insert into sc(sno,cno,grade) values('2020005','20203',90);

在已有表格中添加新字段

use stuinfo
----------------------------------------------------
alter table stu add qq varchar(20)
--在stu表中添加qq字段

删除

drop database stuinfo
--删除stuinfo数据库
----------------------------------------------------
alter table stu drop column qq
--删除qq字段
----------------------------------------------------
drop table stu
--删除stu表
----------------------------------------------------
updata stu set mno=null where mn0=1
--删除时别的表有外键先置null

补充

有时想删除某个表时,提示“无法删除对象 ‘Orders’,因为该对象正由一个 FOREIGN KEY 约束引用”,原因很简单不要急躁,它被其它表的外键引用了,所以无法删除,在此只需先找到哪些表的外键引用了该表的字段。通过系统函数就能解决(SQL Server系统函数提供了非常完善的功能,能代替我们查找和解决许多问题)。

select fk.name,fk.object_id,OBJECT_NAME(fk.parent_object_id) as referenceTableName
from sys.foreign_keys as fk
join sys.objects as o on fk.referenced_object_id=o.object_id
where o.name='被引用的表名'

以上SQL语句能够得到某个表被哪些外键引用,并且也显示出了外键表的表名。通过外键表的表名和外键名称执行以下语句即可删除外键。

ALTER TABLE dbo.被引用的表名 DROP CONSTRAINT 外键名

orderby-聚合函数-groupby

select * from sc order by grade
--查询学生成绩,按照升序排序
select * from sc order by grade desc
--查询学生成绩,按照降序排序
----------------------------------------------------
select count(*) from stu
--统计stu表有多少行
----------------------------------------------------
select distinct sno from sc
select count(distinct sno) from sc
--统计选修课程的学生人数
----------------------------------------------------
select * from sc
select count(grade) from sc
----------------------------------------------------
select avg(grade) from sc where cno='20201'
----------------------------------------------------
select cno,count(sno) from sc group by cno
--求各个课程号以及相对应的选修人数
----------------------------------------------------
select sno,avg(grade) from sc group by sno having avg(grade)>=90
--查询平均成绩>90的学生学号和平均成绩
----------------------------------------------------
--count sum avg max min 
--不可以出现在where语句后面,要使用group by和having

查询

单表查询

select * from stu
--查询表stu的全部信息
----------------------------------------------------
select sno,sname from stu
--查询stu表中的sno,sname字段
----------------------------------------------------
select sname,2019-age as birth_date from stu
--求出生年份
----------------------------------------------------
select distinct sno from sc
--查询有选修课的学生  distinct:去除重复
----------------------------------------------------
select * from stu where sname='小十'
--查询姓名为小十的学生信息
select * from stu where sname like '小十'

select * from sc where cno='20201' and grade>80

select * from stu where age>=18 and age<=19
select * from stu where age between 18 and 19
----------------------------------------------------
select * from stu where mno in (1,2,4)
--查询专业号为01、02、04的学生
----------------------------------------------------
select * from stu where mno not in (1,2,4)
--查询专业号不是01、02、04的学生
----------------------------------------------------
select * from stu where sname like '彭%'
select * from stu where sname like '_小%'
--_是占据一个字节,忽略不计
select * from stu where sname like '%小%'
----------------------------------------------------
select * from sc where grade is null
--查询grade为null的信息

多表查询

连接查询
等值查询
select stu.*,sc.* from stu,sc where stu.sno=sc.sno
--查询每个学生的信息和选修课程的信息  stu.sno=sc.sno起到连接作用
----------------------------------------------------
select saname from stu,sc where stu.sno=sc.sno and sc.cno='20201'
--查询选修20201学生的姓名
多表查询
select stu.*,sc.*,ctime from stu,sc,cou where stu.sno=sc.sno and sc.cno=cou.cno
--查询每个学生的信息和选修课程的信息和学时
左外连接

当我们需要保留一个表的信息的时候就需要左外连接

select stu.*,sc.* from stu left outer join sc on stu.sno=sc.sno
--查询所有学生的信息和选课信息,但是没有选修的学生也要显示出来  stu left outer 保留左表内数据,进行两表连接
----------------------------------------------------
select mno,count(sno) from stu group by mno having mno between 1 and 4
--查询每个专业的人数,假设每个专业都有人
----------------------------------------------------
select major.mno,count(sno) from major left outer join stu
on major.mno=stu.mno
group by major.mno
--查询每个专业的人数,假设每个专业都有人。需要保留major表,左外连接
嵌套查询
不相关的嵌套查询

(子查询不依赖父查询)

select sname from stu where sno in (
    select sno from sc where cno='20201'
)
--查询选修'20201'的学生姓名sname
----------------------------------------------------
select sname from stu where sno in (
    select sno from sc where cno='20202'
)
--选修'20202'的学生的姓名
----------------------------------------------------
--建议使用in而不是=,=返回一个结果,in返回多个结果
相关嵌套查询

(将连接放在子查询里面)

select sname from stu where '20201' in (
    select cno from sc where stu.sno=sc.sno
)
--查询选修'20201'学生的姓名sname
----------------------------------------------------
select sno from sc where 'C语言' in (
    select cname from cou where sc.cno=cou.cno
)
--查询选修了c语言课程的学生学号
----------------------------------------------------
select sno,cno from sc x where grade
>(select avg(grade) from sc y group by sno having x.sno=y.sno)
--查询每个学生超过他平均分的课程号
----------------------------------------------------
--用派生表实现
select sno,cno 
from sc,(select sno,avg(grade) from sc group by sno) as avg_sc(avg_sno,avg_grade)
where sc.sno=avg_sc.avg_sno and grade>avg_grade
--查询每个学生超过他平均分的课程号
带有exists
select sname from stu where exists(
	select * from sc where cno='20201' and stu.sno=sc.sno
)
--查询选修'20201'学生的姓名
----------------------------------------------------
--返回true or false,每次取一个sno连接
集合查询
--集合查询union intersect except
----------------------------------------------------
select sno from stu where age=18 and mno=1
select sno from stu where age=18 intersect select sno from stu where mno=1
select sno from stu where age=18 except select sno from stu where mno!=1
--查询年龄是18且mno=1的学生学号
----------------------------------------------------
select distinct sno from sc where cno in('20201','20203')
select sno from sc where cno='20201' union select sno from sc where cno='20203'
--查询选修'20201'号课程或'20203'的学生学号

视图

视图时从一个或多个基本表(或视图)导出的表。

不同的是,它是虚表,数据库中只存放视图的定义,而不存放视图的对应数据,这些数据仍然存放在原本的基本表中。所以一旦基本表发生变化,从视图中查询的数据也就随之改变。

作用之一:视图更加方便用户的查询

create view v_stu1 as            --2、创建视图
select sno,sname,age from stu    --1、查询stu表信息
select * from v_stu1             --3、查询视图
--查询学生的信息(sno,sname,age)
----------------------------------------------------
create view v_stu2 as
select sno,sname,mname from stu,major where stu.mno=major.mno
select * from v_stu2
--查询学生的信息(sno,sname,mname)
----------------------------------------------------
create view v_stu3 as
select sno,avg(grade) as avg_grade from sc group by sno
select * from v_stu3
--查询学生的信息(sno,avg(grade))
----------------------------------------------------
select sc.sno,cno from sc,v_stu3
where sc.sno=v_stu3.sno
and sc.grade>v_stu3.avg_grade
--查询每个同学较自己平均分高的课程cno
--1、创建每个学生的平均分视图
--2、开始查询

存储过程

事先经过编译并保存在数据库中的一段sql语句集合,使用时调用即可

create proc p1     --创建存储过程
as
begin
	select * from sc where sno='2020005'
end
exec p1            --调用p1
--返回学校2020005学生的成绩情况,存储名p1
----------------------------------------------------
alter proc p1 @sno varchar(13),@cno varchar(13)
as
begin 
	select sc.*,cou.ccredit from sc,cou 
	where sno=@sno and sc.cno=cou.cno
end
exec p1 '2020004','20203'
--查询某学生指定课程号和学分 alter 存储名p1
----------------------------------------------------
drop proc p1
--删除p1

触发器

监听某种情况,并触发某种操作

当对一个表格进行增删改就有可能自动激活执行它

--结构
--create trigger t1 on stu
--after instead of
--update insert delete
--as
--begin
--  .......(代码段)
--end
--begin、end分别表示(、)

----------------------------------------------------

create trigger t1 on stu after insert
as
begin
	if (select count(*) from stu)>17
	begin
		print 'error'
		rollback tran
	end
	else
	begin
		print 'right'
	end
end
--学生人数不能大于17 插入之后进行检测
--以下为测试
insert into stu(sno,sname) values('8','kk')
delete from stu where sno='7'

----------------------------------------------------

alter trigger t1 on stu instead of insert
as
begin
	select * from inserted
	select * from deleted
	if (select count(*) from stu)>16
	begin
		print 'error'
		rollback tran
	end
	else
	begin
		print 'right'
		--insert
		declare @sno varchar(13)
		declare @sname varchar(13)
		declare @age int
		select @sno=sno from inserted
		select @sname=sname from inserted
		select @age=age from inserted
		insert into stu(sno,sname,age) values(@sno,@sname,@age)
	end
end
select count(*) from stu
--在插入之前执行触发器需要在触发器内进行数据插入

----------------------------------------------------

create trigger t2 on stu
after delete
as
begin
	if (select count(*) from stu)<16
	begin
		print 'error'
		rollback
	end
	else
		print 'right'
end
delete from stu where sno='2020001'
--学生人数不能小于16

----------------------------------------------------
create trigger t3 on sc
instead of insert
as 
begin
	declare @sno varchar(13)
	declare @cno varchar(13)
	declare @grade decimal(5,2)
	select @sno=sno from inserted
	select @cno=cno from inserted
	select @grade=grade from inserted
	if @grade >=55 and @grade <=59
	begin
		set @grade=60
	end
	insert into sc values(@cno,@sno,@grade)
end

insert sc values('20202','20200016',57)
select * from sc
--当新增学生成绩55-59改成60

索引

定义:索引时对数据库表中的一列或者多列值进行排序的一种结构

目的:加快查询速度(目录)

但是占用一定的存储空间,更新和维护

不创建

  1. 频繁更新字段或者经常增删改的表不适合创建索引
  2. 表记录太少,不需要创建索引
  3. 如果某些数据包含大量重复数据,因此建立索引就没有太大的效果,例如性别字段,只有男女,不适合建立索引
  4. stu sex 0 1

其实SQL server创建表时建立聚集索引

聚集索引定义:数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能有一个聚集索引

非聚集索引定义:数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序可能不同,一个表中可以有一个或多个非聚集索引

create unique index scno on sc(sno asc,cno desc)
drop index scno on sc
--sc表按学号升序和课程号降序建立唯一索引
--删除索引scno

游标

定义:用来操作查询的结果集,是一个用户数据缓冲区

具体描述(光标)

优点:保存查询结果,方便以后使用。游标的结果集时select执行结果,需要的时候,只需一次,不用重复的查询

缺点:数据缓冲区,如果游标数据量大则会造成内存不足,所以,在数据量小时才使用游标

步骤

1、声明游标

2、打开游标

3、取数据(循环)

4、关闭游标或者deallocate

--语法
--游标名 cursor for select ...


declare my_cursor cursor for select mname from major
declare @mname varchar(30)
-- 声明游标
----------------------------------------------------
open my_cursor
-- 打开游标
----------------------------------------------------
fetch next from my_cursor into @mname
while @@FETCH_STATUS=0
begin
	select @mname as 'mname'
	fetch next from my_cursor into @mname
end
-- 取数据(循环)
----------------------------------------------------
deallocate my_cursor
-- 关闭游标或者deallocate
----------------------------------------------------
select * from sc
declare my_cursor cursor for select cno,sno,grade from sc
declare @cno varchar(13)
declare @sno varchar(13)
declare @grade decimal
open my_cursor
fetch next from my_cursor into @cno,@sno,@grade
while @@FETCH_STATUS=0
begin
	if @grade >=80
		update sc set sc_rank='A' where cno=@cno and sno=@sno
	else if @grade>=70
		update sc set sc_rank='B' where cno=@cno and sno=@sno
	else if @grade>=0
		update sc set sc_rank='C' where cno=@cno and sno=@sno
	fetch next from my_cursor into @cno,@sno,@grade
end
deallocate my_cursor
select * from sc
--对sc表添加一个等级列,若学生成绩80以上等级A,70-79分为B,其余为C,null仍为null
----------------------------------------------------
select * from stu
select * from stu left outer join major 
on stu.mno=major.mno
declare my_cursor cursor for select sname,mname from stu left outer join major on stu.mno=major.mno
declare @sname varchar(30)
declare @mname varchar(30)
open my_cursor
fetch next from my_cursor into @sname,@mname
while @@FETCH_STATUS=0
begin
	select @sname as 'sname',@mname as 'mname'
	fetch next from my_cursor into @sname,@mname
end
close my_cursor
--查询所有学生的专业名和姓名

与视图比较

  1. 本质不同:一个是作为指针操作,一个是作为数据库对象
  2. 占用资源:多和少
  3. 工作方式:一个行处理,一个整个表(查询结果
  4. 数据库操作不同

MYSQL数据库

启动MySQL

打开命令提示符(以管理员身份运行)

输入

net start mysql

启动数据库

mysql -u root -p

mysql -u (用户名) -p 登陆用户(连接本机)

启动数据库服务器所在的主机名

mysql -h (数据库服务器所在的主机名) -P(这里是大写P。后面跟你要连接的服务器的端口号)-u(用户名) -p(密码)

创建数据库

create database if not exists 数据库名称 字符集;

例如:

create database if not exists student character set utf8;

(student为数据库名称,character set utf8为字符集,数据库不能重名)

查看MYSQL服务器主机上的数据库

show databases;

修改数据库

alter database student

character set latin1

collate latin1_german1_ci;

(student为数据库名称,latin1为字符集,latin1_german1_ci为排序规则)

查看数据库信息

show create database student;

(student为数据库名称)

删除数据库

Drop database student;

(student为数据库名称)

创建数据表

CREATE TABLE 藏书信息

(

图书编号 CHAR(12) not null,

ISBN编号 VARCHAR(20) not null,

总藏书量 SMALLINT not null,

馆内剩余 SMALLINT not null,

藏书位置 VARCHAR(20) not null,

入库时间 DATE null

)

(“藏书信息”为表名称,“图书编号”为字段名,“CHAR(12)”为数据类型,括号内的“12”为长度,not null表示不允许为空,null表示允许为空)

增加数据表中的数据

INSERT INTO 藏书信息(图书编号,ISBN编号,总藏书量,馆内剩余,藏书位置,入库时间)

VALUES

('TP7040273144','9787121201478','30','30','A-1-1','2015/6/10'),

('YP7111229827','9787111220827','20','20','A-1-1','2014/5/18')

(藏书信息为数据表名称,橙色部分必须输入要添加信息的表中所有的字段名,蓝色部分为内容,需要对应字段名输入)

修改数据表中的数据

UPDATE 表名 SET 要修改的值 WHERE 唯一的值

例如:

UPDATE `借书证` SET 借书证编号="0123456" WHERE 借书证编号=‘0016585’

删除数据表中的数据

DELETE FROM (表名)WHERE (要删除的数据中的唯一值)

例如:

DELETE FROM `借书证` where 借书证编号=‘0016584’

计算整个表

计算减法

SELECT (要显示的字段) AS (计算是该字段显示的名称),(要显示的字段) AS (计算是该字段显示的名称), (要显示的字段), (要显示的字段), (被减字段)-(减去字段) AS (计算完后结果的字段名) FROM (表名)

例如:

SELECT 图书编号 AS BOOKID,ISBN编号 AS ISBNID,总藏书量,馆内剩余, 总藏书量-馆内剩余 AS 借出数量 FROM 藏书信息

(AS为修改字段名称)

计算加法

SELECT (要显示的字段) AS (计算是该字段显示的名称),(要显示的字段) AS (计算是该字段显示的名称), (要显示的字段), (要显示的字段), (被加字段)+(加的字段) AS (计算完后结果的字段名) FROM (表名)

单独计算减去表中的某个数据

SELECT (要显示的字段), (要显示的字段), (被减字段)-(减去字段) AS (计算完后结果的字段名) FROM (表名) WHERE (要计算的数据中的唯一值)

例如:

SELECT 进货数量,卖出数量, 进货数量-卖出数量 AS 剩余数量 FROM 商品信息表 WHERE 商品编号=‘s6006'

AS:修改字段名或增加字段

查询满足某些条件的数据

SELECT*FROM (表名) WHERE(需要满足的值,“=”也可以为“>”,“<”)

例如:

SELECT*FROM `图书信息表` WHERE 价格=38

也可以添加and、or使用,例如(满足价格=38并且图书类型是漫画的):

SELECT*FROM  `图书信息表` WHERE 价格=38 and 图书类型=’漫画’

满足价格=38或者满足类型是漫画的:

SELECT*FROM  `图书信息表` WHERE 价格=38 or 图书类型=’漫画’

And=和 or=或

LIKE查询

模糊查询

SELECT*FROM (表名)WHERE (查询的字段名)like (‘%数据库%’%为占位符)

例如:

SELECT*FROM `藏书信息` WHERE `图书编号` like '%6'

确定字符长度的情况下

SELECT*FROM ‘表名’WHERE like (谭__)

例如:

SELECT*FROM `藏书信息` WHERE `总藏书量` like '3%'

排序

对全表进行升序

SELECT*FROM (表名)order by (排序的字段)

例如:

SELECT*FROM `藏书信息` order by `图书编号`

对全表进行降序

SELECT*FROM ‘表名’order by ‘排序的字段’ desc

例如:

SELECT*FROM `藏书信息` order by `图书编号` desc

对部分进行升序

SELECT*FROM ‘表名’where ‘’=‘’ order by ‘排序的字段’

SELECT*FROM `藏书信息` WHERE ‘馆内剩余’>10 ORDER BY ‘图书编号’

对部分进行降序

SELECT*FROM ‘表名’where (需要满足的条件) order by ‘排序的字段’ desc

例如:

SELECT*FROM `藏书信息` WHERE ‘馆内剩余’>10 ORDER BY ‘图书编号’ desc

查询记录

SUM(和) MIN(最小) MAX(最大) AVG(平均值) COUNT(*)(统计数据表中的总记录数)

SELECT Count(*)FROM ‘表名’

例如:

SELECT Count(*)FROM `藏书信息`

SELECT Count(*)as (显示结果的字段名) FROM ‘表名’

例如:

SELECT Count(*)as 总数 FROM `藏书信息`

SELECT Count(*)as 总数 FROM ‘表名’ where(需要满足的条件)

例如:

SELECT Count(*)as 总数 FROM `藏书信息` where `总藏书量`='30'

SELECT SUM(需要计算的字段名) FROM ‘表名’

例如:

SELECT SUM(总藏书量) FROM `藏书信息`

统计 将数据进行分组汇总

Select avg(价格) from 图书信息 group by 图书类型
Select 图书类型,avg(价格) as 平均价格 from 图书信息 group by 图书类型

//统计每种类型的图书的平均价格

Select 出版社,Max(价格) as 最高价格 from 图书信息 group by 出版社

//统计每种类型图书的最高价格

SELECT `出版社` , AVG(价格) AS 平均价格,COUNT(*) as 图书种数 FROM `图书信息1`

//将图书信息表中的数据全部检索出来

GROUP BY `出版社` HAVING AVG(价格)> 20 AND COUNT(*)>1

//GROUP BY 将出版社表进行分组查询,HAVING 在分组后过滤信息,只显示平均价格大于20并且图书种数超过1的数据

ORDER BY 平均价格 DESC;

//进行降序排列

group by:在分类的基础上再进行查询 HAVING:过滤作用

where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,where条件中不能包含聚组函数,使用where条件过滤出特定的行。

having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件过滤出特定的组,也可以使用多个分组标准进行分组。

多表连接查询

SELECT A.`图书编号`,A.`ISBN编号`,A.`总藏书量`,B.`图书名称`,C.`出版社名称` 
FROM `藏书信息` AS A ,`图书信息1` AS B ,`出版社1` AS C 
WHERE A.`ISBN编号`=B.`ISBN编号` AND B.`出版社`=C.`出版社IP`
//创建等值连接
AND A.`总藏书量`>20

内连接查询

等值连接查询

SELECT
D.`ISBN编号`,D.`图书名称`,D.`出版日期`,D.`出版社`,E.`出版社名称`,E.`出版社IP` 
FROM `图书信息` AS D INNER JOIN `出版社` AS E
ON D.`出版社`=E.`出版社IP`

等值连接查询

SELECT F.`图书名称`,F.`价格`,F.`出版日期`,F.`图书类型`,G.`图书类型名称`
FROM `图书信息` AS F INNER JOIN `图书类型` AS G
//连接图书信息表和图书类型表并删除两表中不匹配的行,只显示匹配的行
ON F.`图书类型`=G.`图书类型编号`
AND F.`价格` BETWEEN 10 AND 30
//在10-30这个范围内进行查询
AND F.`价格`>10
AND G.`图书类型名称`='开发'

BETWEEN:在某个范围内进行查询

INNER JOIN(内连接),也称为自然连接

作用:根据两个或多个表中的列之间的关系,从这些表中查询数据。
注意: 内连接是从结果中删除其他被连接表中没有匹配行的所有行,所以内连接可能会丢失信息。
重点:内连接,只查匹配行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1aZjseTS-1606205166473)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml9904\wps1.jpg)]

sql语句定义的顺序

转载于:

https://blog.csdn.net/u013887008/article/details/93377939

(1) SELECT (2)DISTINCT<select_list>

(3) FROM <left_table>

(4) <join_type> JOIN <right_table>

(5)     ON <join_condition>

(6) WHERE <where_condition>

(7) GROUP BY <group_by_list>

(8) WITH {CUBE|ROLLUP}

(9) HAVING <having_condition>

(10) ORDER BY <order_by_condition>

(11) LIMIT <limit_number>

sql语句执行顺序

(8) SELECT (9)DISTINCT<select_list>

(1) FROM <left_table>

(3) <join_type> JOIN <right_table>

(2)     ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH {CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY <order_by_list>

(11) LIMIT <limit_number>

可以看到,一共有十一个步骤,最先执行的是FROM操作,最后执行的是LIMIT操作。每个操作都会产生一个虚拟表,该虚拟表作为一个处理的输入,看下执行顺序

(1) FROM:对FROM子句中的左表<left_table>和右表<right_table>执行笛卡儿积,产生虚拟表VT1;
(2) ON: 对虚拟表VT1进行ON筛选,只有那些符合<join_condition>的行才被插入虚拟表VT2;
(3) JOIN: 如果指定了OUTER JOIN(如LEFT OUTER JOIN、RIGHT OUTER JOIN),那么保留表中未匹配的行作为外部行添加到虚拟表VT2,产生虚拟表VT3。如果FROM子句包含两个以上的表,则对上一个连接生成的结果表VT3和下一个表重复执行步骤1~步骤3,直到处理完所有的表;
(4) WHERE: 对虚拟表VT3应用WHERE过滤条件,只有符合<where_condition>的记录才会被插入虚拟表VT4;
(5) GROUP By: 根据GROUP BY子句中的列,对VT4中的记录进行分组操作,产生VT5;
(6) CUBE|ROllUP: 对VT5进行CUBE或ROLLUP操作,产生表VT6;
(7) HAVING: 对虚拟表VT6应用HAVING过滤器,只有符合<having_condition>的记录才会被插入到VT7;
(8) SELECT: 第二次执行SELECT操作,选择指定的列,插入到虚拟表VT8中;
(9) DISTINCT: 去除重复,产生虚拟表VT9;
(10) ORDER BY: 将虚拟表VT9中的记录按照<order_by_list>进行排序操作,产生虚拟表VT10;
(11) LIMIT: 取出指定街行的记录,产生虚拟表VT11,并返回给查询用户

一些后来自学的内容

MySQL中concat函数

源:https://www.jb51.net/article/100886.htm

使用方法:

CONCAT(str1,str2,…) 

返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。

注意:

如果所有参数均为非二进制字符串,则结果为非二进制字符串。

如果自变量中含有任一二进制字符串,则结果为一个二进制字符串。

一个数字参数被转化为与之相等的二进制字符串格式;若要避免这种情况,可使用显式类型 cast, 例如:

SELECT CONCAT(CAST(int_col AS CHAR), char_col)

MySQL的concat函数可以连接一个或者多个字符串,如

mysql> select concat('10');

+--------------+
| concat('10') |
+--------------+
| 10  |
+--------------+
1 row in set (0.00 sec)

mysql> select concat('11','22','33');

+------------------------+
| concat('11','22','33') |
+------------------------+
| 112233 |
+------------------------+
1 row in set (0.00 sec)

MySQL的concat函数在连接字符串的时候,只要其中一个是NULL,那么将返回NULL

mysql> select concat('11','22',null);

+------------------------+
| concat('11','22',null) |
+------------------------+
| NULL  |
+------------------------+
1 row in set (0.00 sec)

MySQL中concat_ws函数

使用方法:

CONCAT_WS(separator,str1,str2,…)

CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。

注意:

如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。

如连接后以逗号分隔

mysql> select concat_ws(',','11','22','33');

+-------------------------------+
| concat_ws(',','11','22','33') |
+-------------------------------+
| 11,22,33 |
+-------------------------------+
1 row in set (0.00 sec)

和MySQL中concat函数不同的是, concat_ws函数在执行的时候,不会因为NULL值而返回NULL

mysql> select concat_ws(',','11','22',NULL);

+-------------------------------+
| concat_ws(',','11','22',NULL) |
+-------------------------------+
| 11,22 |
+-------------------------------+
1 row in set (0.00 sec)

MySQL中group_concat函数

完整的语法如下:

group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

基本查询

mysql> select * from aa;
+------+------+
| id| name |
+------+------+
|1 | 10|
|1 | 20|
|1 | 20|
|2 | 20|
|3 | 200  |
|3 | 500  |
+------+------+
6 rows in set (0.00 sec)


以id分组,把name字段的值打印在一行,逗号分隔(默认)

mysql> select id,group_concat(name) from aa group by id;
+------+--------------------+
| id| group_concat(name) |
+------+--------------------+
|1 | 10,20,20|
|2 | 20 |
|3 | 200,500|
+------+--------------------+
3 rows in set (0.00 sec)


以id分组,把name字段的值打印在一行,分号分隔

mysql> select id,group_concat(name separator ';') from aa group by id;
+------+----------------------------------+
| id| group_concat(name separator ';') |
+------+----------------------------------+
|1 | 10;20;20 |
|2 | 20|
|3 | 200;500  |
+------+----------------------------------+
3 rows in set (0.00 sec)

以id分组,把去冗余的name字段的值打印在一行,

逗号分隔

mysql> select id,group_concat(distinct name) from aa group by id;
+------+-----------------------------+
| id| group_concat(distinct name) |
+------+-----------------------------+
|1 | 10,20|
|2 | 20  |
|3 | 200,500 |
+------+-----------------------------+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序

mysql> select id,group_concat(name order by name desc) from aa group by id;
+------+---------------------------------------+
| id| group_concat(name order by name desc) |
+------+---------------------------------------+
|1 | 20,20,10  |
|2 | 20|
|3 | 500,200|
+------+---------------------------------------+
3 rows in set (0.00 sec)

repeat()函数

用来复制字符串,如下’ab’表示要复制的字符串,2表示复制的份数

mysql> select repeat('ab',2);

+----------------+
| repeat('ab',2) |
+----------------+
| abab      |
+----------------+

1 row in set (0.00 sec)

又如

mysql> select repeat('a',2);

+---------------+
| repeat('a',2) |
+---------------+
| aa      |
+---------------+
1 row in set (0.00 sec)
mysql> select id,group_concat(name separator ';') from aa group by id;
+------+----------------------------------+
| id| group_concat(name separator ';') |
+------+----------------------------------+
|1 | 10;20;20 |
|2 | 20|
|3 | 200;500  |
+------+----------------------------------+
3 rows in set (0.00 sec)

以id分组,把去冗余的name字段的值打印在一行,

逗号分隔

mysql> select id,group_concat(distinct name) from aa group by id;
+------+-----------------------------+
| id| group_concat(distinct name) |
+------+-----------------------------+
|1 | 10,20|
|2 | 20  |
|3 | 200,500 |
+------+-----------------------------+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序

mysql> select id,group_concat(name order by name desc) from aa group by id;
+------+---------------------------------------+
| id| group_concat(name order by name desc) |
+------+---------------------------------------+
|1 | 20,20,10  |
|2 | 20|
|3 | 500,200|
+------+---------------------------------------+
3 rows in set (0.00 sec)

repeat()函数

用来复制字符串,如下’ab’表示要复制的字符串,2表示复制的份数

mysql> select repeat('ab',2);

+----------------+
| repeat('ab',2) |
+----------------+
| abab      |
+----------------+

1 row in set (0.00 sec)

又如

mysql> select repeat('a',2);

+---------------+
| repeat('a',2) |
+---------------+
| aa      |
+---------------+
1 row in set (0.00 sec)
  • 1
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肚子好饿-

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值