SQL常用语句大全

创建表and插入数据

课程表

create database stuinfo --创建表

use stuinfo				--使用表

create table major(
	mno varchar(20),--设置主键或者  mno varchar(20) primary key,
	mname varchar(20),
	primary key(mno)--设置主键
)
drop table 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,'人工智能')
insert into major (mno,mname) values(5,'计算机科学与技术')

select * from major

学生表

create table stu(
	sno varchar(30), --或者sno varchar(30) primary key ,设置主键  --学号
	sname varchar(30) not null,									--名字
	age smallint,												--年龄
	sex bit,													--性别0女 1男
	mno varchar(20),											--专业号
	primary key(sno),
	foreign key(mno) references major(mno) --foreign key(mno) references major(mno) 外键链接  major表的mno
)
drop table stu
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);

课程表

create table cou(
	cno varchar(30),			--课程号
	cname varchar(30) not null,	--课程名
	ctime smallint,				--课时
	ccredit decimal(4,2)		--学分
	primary key(cno)
)

drop table 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 cou

成绩表

create table sc(
	sno varchar(30),		--学号
	cno varchar(30),		--课程号
	grade decimal(5,2)		--成绩
	primary key (sno,cno)	--主键(两个)
	foreign key(sno) references stu(sno) --外键
)

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

select * from sc

–对sc表加一个外键

alter table sc add constraint fk_sc foreign key(cno) references cou(cno)

–添加qq字段

alter table stu add qq varchar(20)

select * from stu

–删除qq字段

alter table stu drop column qq

–创建表 删除表

--创建表 
create table t(
	t int 
 )
select * from t

--删除表
drop table t

select * from major

–删除一个专业(外键关联)

--删除一个专业 --失败
delete from major where mno=1
--别的表有外键的先置成NULL update 

update stu set mno=null where mno=1

delete from major where mno=1

更新一条数据

--学号为2020002的同学改名为小一
update stu set sname='小小' where sno='2020002'
select * from stu

升序 降序 查询

--升序
select * from sc order by grade 

--降序
select * from sc order by grade  desc

聚集函数 count

select COUNT(sno) from sc

查询学生人数 去掉重复的sno学号 distinct

select COUNT(distinct sno) from sc

查询20201课程的学生平均成绩

select AVG(grade) from sc where cno='20201' 

查询课程号20201 最高成绩的分数 最小值 最大值 min max

select min(grade) from sc where cno='20201'
select max(grade) from sc where cno='20201'

求各个课程号以及相应的选修人数 group by

//group by 根据什么划分 根据cno划分前面一定要有cno
select cno,COUNT(distinct sno) as num from sc group by cno

查询平均成绩大于等于90的学生号和平均成绩

--注意where字句不能用聚集函数作为条件表达式 
--如果一定要使用 聚集函数 要使用 having 而且还要搭配 group by 使用
select sno ,AVG(grade) from sc group by sno having AVG(grade)>=90

查询选修了‘20201’学生的姓名sname

select sname from stu,sc where stu.sno=sc.sno and cno='20201'

多表查询

链接查询 (等值链接)

--查询每个学生的信息和选修课程的信息
select stu.*,sc.* from stu,sc where stu.sno=sc.sno

查询选修了‘20201’学生的姓名sname

select sname from stu,sc where stu.sno=sc.sno and cno='20201'

–多表链接

--查询每个学生的信息和选修课程信息和学时
select stu.*,sc.*,ctime from stu,sc,cou where stu.sno=sc.sno and sc.cno=cou.cno

左外链接

(当需要保存一个表的信息时就需要用到左外链接)left outer join 条件是用的 on

--查询所有的学生信息和选课信息,但是没有选修的学生也要显示出来
select stu.*,sc.* from stu left outer join sc on stu.sno=sc.sno

查询每个专业的学生人数,假设每个专业都有学生

select mno,COUNT(sno) from stu group by mno having mno between 1 and 4

–查询每个专业的人数,但有的专业可能没有人

select * from major
select major.mno,COUNT(sno) as num from major left outer join stu on major.mno=stu.mno group by major.mno

嵌套查询

不相关嵌套查询(子查询不依赖父查询)

--查询选修‘20201’学生的姓名sname
select sname from stu where sno in (select sno from sc where cno='20201') --查询有多条信息用in

select sname from stu where sno = (select sno from sc where cno='20202')  --查询只有一条信息可以用 =   建议统一用in

相关嵌套查询

--查询选修‘20201’学生的姓名和学号
select sname from stu where '20201' in(select cno from sc where stu.sno=sc.sno)
--查询选择'C语言'课程的学号
select sno from sc where 'C语言' in(select cname from cou where sc.cno=cou.cno)
--查询每个学生超过他的平均分的课程号  第二种方法用派生表实现
select  sno,cno
from sc x
where 
grade > (select AVG(grade) from sc y group by sno having x.sno=y.sno) --x和y 为别名
--派生表方式 就是在创建一个表(并不是在数据库中创建一个表而是查询中创建的表)
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
--查询选修’20301‘课程 学生的姓名sname
select sname from stu where sno in (select sno from sc where cno='20201')
select sname from stu where exists(
	select *from sc where cno='20201' and stu.sno=sc.sno
)--返回true false,每次取一个sno链接

---集合查询 union intersect except
--查询年龄是十八的学生学号 intersect
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

--查询选修'20201'号课程或'20203'的学生号
select * from sc
select distinct sno from sc where cno='20201' intersect select distinct sno from sc where cno='20203'

查看表的主键

select "COLUMN_NAME" FORM "ALL_CONS_COLUMS" WHERE "TABLE_NAME"=‘TABLE_NAME’ AND ("CONSTRAINT_NAME" LIKE%_PKEY’ OR "CONSTRAINT_NAME" LIKE ‘PK_%);

视图

视图是从一个或几个基本表(或视图)到出的表。不同的是,它是一个虚表,数据库中只存放视图的定义,而不存放视图对应的数据,这些数据仍然存放在原来的基本表中。所以一旦基本表改变,从视图中查询出的数据也随之改变。
作用之一: 视图更加方便用户的查询。

视图的基本操作

  1. 创建视图在这里插入代码片
create view v_stul as select sno,sname,age from stu
  1. 查询视图
select * v_stul
  1. 删除视图
drop view v_stul
  1. 删除原表的数据试图视图,从视图中查询出的数据也随之改变。
create view v_major as select * from mojor

select * from v_major

delete from major whele mno=5
再次查询,视图查询内容以改变
create view v_stul as select sno,sname,age from stu
  1. 查询学生的信息(sno,sname,mname)
创建视图
create view v_stu2
as
select sno,sname,mname from stu ,major where stu.mno=major.mno

select * from v_stu
  1. 查询学生的信息(sno,avg(grade))
select sno,AVG(grade) from sc group by sno

create view v_stu3
as
select sno,AVG(grade) as avg_grade from sc group by sno

select * from v_stu3

平均分小于70
select * from v_stu3 whele avg_grade<70
  1. 查询每个同学较自己平均分高的课程cno
每个同学的平均分视图:v_stu3
select sc.sno,cno from sc,v_stu3 whele sc.sno=v_stu3.sno and sc.grade>v_stu3.avg_grade

存储过程

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

  1. 返回学号2020005学生的成绩情况 储存名为p1
select * from sc where sno='2020005'

--创建存储过程
create proc p1
as
begin
	select * from sc where sno='2020005'
end

--调用存储过程
exec p1
  1. 查询某学生指定的课程号的成绩和学分 alter 存储名 p1
--alter 修改存储过程
alter proc p1 @sno varchar(13),@cno varchar(13)
as
begin
	select sc.* ,cou.ccredit from sc,cou whele sno=@sno and sc.cno=@cno and sc.cno=cou.cno
end

exec p1 '2020004','20203'
  1. 删除存储过程 p1
drop proc p1

触发器

定义: 监视某种情况,并出发某种操作,当对一个表格进行增删改就能自动激活执行它

create trigger t1 on stu
after insert of 
insert delete update
as
begin
---触发器内容 代码
end
  1. 创建触发器

学生的人数不能大于17

create trigger t1 on stu after insert ---after insert 插入完之后触发
as
begin
	if(select COUNT(*) from stu)>17
	begin
		print 'error'
		rollback tran
	end
	else
	begin
		pring 'right'
	end
end

---select COUNT(*) from stu 查询人数
---drop trigger t1 删除触发器t1
  1. 触发器的使用
---插入超过17 自动出发 
insert into stu(sno,sname) values('20200018','kk')

打印 ‘error’
并返回取消执行
在这里插入图片描述

  1. 触发器(先判断后执行)
---先判断后执行
alter trigger t1 on stu instead of insert
as
begin
	select * from inserted
	select * from deleted
	if(select COUNT(*) from stu)>17
	begin
		print 'error'
		rollback tran
	end
	else
	begin
		print 'right'
		--insert
		declare @sno varchar(13)
		declare @sname varchar(30)
		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
  1. 触发器
create trigger t1 on stu after delete---after insert 插入完之后触发
as
begin
	if(select COUNT(*) from stu)<16
	begin
		print 'error'
		rollback tran
	end
	else
	begin
		pring 'right'
	end
end

删除学生触发触发器

delete from stu where sno='20200016'

在这里插入图片描述

当新增学生成绩为55-59 改为60分

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

函数

自定义函数

函数和存储过程很像,不同之处就是函数多了一个return

  1. 例1:计算某门课程的平均分
create function fun1(@con varchar(13))
returns int
as
begin
	declare @avgscore int
	select @avgsore=avg(grade)from sc where con=@ano
	returns @avgscore
end

调用函数fun1()

---需要加dbo.来执行fun1函数
select dbo.fun1('20202');
  1. 例2:输入专业号,返回学生号和姓名
--create function fun2(@mno int)--创建
alter function fun2(@mno int)--修改
returns @snoSname table(
	sno varchar(13)
	sname varchar(30)
)
as
begin
	insert into @anoSname(ano,sname) select sno,sname from stu where mno=@mno
end

--执行函数
select * from dbo.fun2(1)
  1. 例3:输入专业号,返回这个专业所有学生的每个课程对应成绩的一个表
create function fun3(@mno int)--修改
returns @snoSname table(
	sno varchar(13)
	cno varchar(13)
	grade decimal(5,2)
)
as
begin
	insert into @mSc select stu.sno,cno,grade from major,stu,sc where major.mno=stu.mno and stu.sno=sc.sno and stu.mno=@mno
	return
end

--执行函数fun3
select * from fun3(1)

在这里插入图片描述

索引

定义:索引是对数据库表中的一列或者多列值进行排序的一种结构
目的:加快查询的速度(目录)select
但是占用一定的存储空间,

不建议创建索引:

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

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

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

--删除索引scno
drop index scno on sc

游标

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

具体描述(光标)
fetch
在这里插入图片描述
优点:
保存查询结果,以便以后使用。游标结果集是select执行结果,需要的时候,只需一次,不用重复查询。
缺点:
数据缓冲区,如果游标数据量大则会造成内存不足。
所以,在数据量小时才使用游标

语法:

declare 游标名 cursor for select ...

步骤

  1. 声明游标
declare my_cursor cursor for select *from major
  1. 打开游标
open my_sursor
  1. 取数据(循环)
--首先定义变量
declare @mname varchar(30) 

fetch next from my_cursor into @mname
while @FETCH_STATUS=0
begin
	select @mname as 'mname'
	fetch next from my_cursor into @mname
end
  1. 关闭游标 或者 deallocate
deallocate my_cursor

–对sc表添加一个等级列,若学生成绩80以上等级A,70-79分为B,其余为C,null仍为null

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


--查询所以学生的专业名和姓名
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. 数据库操作不同
    在这里插入图片描述

视频教程见 B站 @DJ同学

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值