SQL



--私人笔记使用,请勿转载

 


--可以下载简易的H2数据库练习SQL,才8M大哦,直接运行bin下面的h2.bat 即可。
--注意字符串用''!
-------------一-------------
--查询中用到的关键词主要包含六个,并且他们的顺序依次为
--select--from--where--group by--having--order by 
--其中select和from是必须的,其他关键词是可选的,这六个关键词的执行顺序
--与sql语句的书写顺序并不是一样的,而是按照下面的顺序来执行
--from--where--group by--having--select--order by,
--from:需要从哪个数据表检索数据 
--where:过滤表中数据的条件
--group by:如何将上面过滤出的数据分组
--having:对上面已经分组的数据进行过滤的条件 
--select:查看结果集中的哪个列,或列的计算结果 搜索
--order by :按照什么样的顺序来查看返回的数据

 

-------------二-------------
--from后面的表关联,是自右向左解析的,而where条件的解析顺序是自下而上的。
--也就是说,在写SQL文的时候,尽量把数据量大的表放在最右边来进行关联,
--而把能筛选出【大量数据的条件】放在where语句的最下面。

 

-------------三、Join-------------
--left join   :左连接,返回左表中所有的记录以及右表中连接字段相等的记录。
--right join :右连接,返回右表中所有的记录以及左表中连接字段相等的记录。
--inner join :内连接,又叫等值连接,只返回两个表中连接字段相等的行。
--full join :外连接,返回两个表中的行:left join + right join
--cross join :结果是笛卡尔积,就是第一个表的行数乘以第二个表的行数。

 


 举例:

 


select * from a;
编号 姓名
---- ----------
1000 张三
2000 李四
3000 王五

 


select * from b;
编号 商品
---- ----------
1000 电视机
2000 录像机
4000 自行车

 


select a.*,b.* from a inner join b on a.编号=b.编号;
编号 姓名 编号 商品
---- ---------- ---- ----------
1000 张三 1000 电视机
2000 李四 2000 录像机

 


select a.*,b.* from a left join b on a.编号=b.编号;
编号 姓名 编号 商品
---- ---------- ---- ----------
1000 张三 1000 电视机
2000 李四 2000 录像机
3000 王五 空值 空值

 


select a.*,b.* from a right join b on a.编号=b.编号;
编号 姓名 编号 商品
---- ---------- ---- ----------
1000 张三 1000 电视机
2000 李四 2000 录像机
 空值 空值 4000 自行车

 


select a.*,b.* from a full join b on a.编号=b.编号;
编号 姓名 编号 商品
---- ---------- ---- ----------
1000 张三 1000 电视机
2000 李四 2000 录像机
3000 王五 空值 空值
 空值 空值 4000 自行车
 
-------------四、SQL练习题1-------------

 

 --1)group by
--info 表
--date result
--2005-05-09 win
--2005-05-09 lose
--2005-05-09 lose
--2005-05-09 lose
--2005-05-10 win
--2005-05-10 lose
--2005-05-10 lose

 

--如果要生成下列结果, 该如何写sql语句?
--           win lose
--2005-05-09 2 2
--2005-05-10 1 2

 

--(1)
Select date, count(a.result) as win from info a where result="win"  group by date join
     Select count(b.result) as lose from info b wehre b.result="lose"  group by date  on a.date=b.date

 

--(2)
Select date, count(a.result) as win from info a where result="win"  join
     Select count(b.result) as lose from info b wehre b.result="lose" on a.date=b.date
 group by date
 
--(3)
select a.date, a.result as win, b.result as lose from
  (select date, count (result) as result from info where result = "win" group by date) as a
  join
  (select date, count (result) as result from info where result = "lose" group by date) as b

 

on a.date = b.date;
--(4)
select date , sum( case when result = "win" then 1 else 0 end ) as "win",
sum(case when result = "lose" then 1 else 0 end) as "lose" from info group by date;

 

--2)case when then else......
--表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列

 

select (case when a>b then a else b), (case when b>c then b else c) from table;

 

--3)case when then......when then......else......
 --有一张表,里面有3个字段:语文,数学,英语。其中有3条记录分别表示语文70分,数学80分,英语58分,
 --请用一条sql语句查询出这三条记录并按以下条件显示出来(并写出您的思路):
--大于或等于80表示优秀,大于或等于60表示及格,小于60分表示不及格。

 

--显示格式:
--语文 数学 英语
--及格 优秀 不及格
------------------------------------------

 

select (case when score>=80 then youxiu
when score >=60 then jige
else bujige) as ’语文‘,
(case when score >=80 then youxiu
when score >=60 then jige
else bujige) as ‘数学’,
(case when score>=80 then youxiu
when score>=60 then jige
else bujige) as ’英语‘
   from table;

 

--4).姓名:name 课程:subject 分数:score 学号:stuid
--张三 数学 89 1
--张三 语文 80 1
--张三 英语 70 1
--李四 数学 90 2
--李四 语文 70 2
--李四 英语 80 2
--题解:
--1.计算每个人的总成绩并排名(要求显示字段:姓名,总成绩)//Q1 主键是学号
select name, sum(score) as 总成绩 from studentscore group by name order by 总成绩;

 

--2.Sum()计算每个人的总成绩并排名(要求显示字段: 学号,姓名,总成绩)//Q1
(1)select stuid, name, sum(score) as 总成绩 from studentscore group by stuid order by 总成绩; --(错误查询)
(2)select distinct t1.stuid,t1.name,t2.allscore from stuscore t1,( select stuid,sum(score) as allscore
   from stuscore group by stuid)t2
     where t1.stuid=t2.stuid order by t2.allscore desc
 
--3.Max():计算每个人单科的最高成绩(要求显示字段: 学号,姓名,课程,最高成绩) //Q1
(1)select stuid, name, subject, max(score) as score from studentscore group by stuid; --(错误查询)
(2)select t1.stuid, t1.name, t1.subject, t2.score from studentscore t1, (select stuid, max(score) as score from studentscore group by stuid) t2
    where t1.stuid=t2.stuid and t1.score=t2.score;

 

--4.AVG():计算每个人的平均成绩(要求显示字段: 学号,姓名,平均成绩)//Q1
(1)select stuid, name, AVG(score) as averagescore from studentscore group by stuid;--(错误查询)
(2) select t1.stuid, t1.name, t2.avgscore from studentscore t1, (select stuid, avg(score) as avgscore from studentscore group by stuid) as t2 where t1.stuid=t2.stuid;

 

--5.Max():列出各门课程成绩最好的学生(要求显示字段: 学号,姓名,科目,成绩)//Q2 #2 and #3的区别
(1)select stuid, name, subject, max(score) as score from studentscore group by subject order by subject;--(错误查询)
(2)select t1.stuid, t1.name, t1.subject,t2.score from studentscore t1, (select stuid,distinct subject, max(score) as score from studentscore group by subject) as t2
   where t1.stuid=t2.stuid and t1.score=t2.score;
(3) select t1.stuid, t1.name, t1.subject, t2.score from studentscore t1,(select subject, max(score) as score from studentscore group by subject) t2
   where t1.subject=t2.subject and t1.score=t3.score
  
--6.Top2: 列出各门课程成绩最好的两位学生(要求显示字段: 学号,姓名,科目,成绩)
(1)select stuid, name, subject,score from studentscore where count(0) as rank in ('1','2') group by subject order by score desc. --(错误查询)
(2)select distinct t1.* from studentscore t1 where t1.stuid in (select top2 stuid from studentscore group by suject where subject=t1.subject order by score desc)
order by t1.subject;

 

--7.Sum()/count(*):统计如下:学号 姓名 语文 数学 英语 总分 平均分
(1)select stuid, name, (select score fron studentscore where subject= '语文') as 语文,
(select score from studentscore where subject ='数学' ) as 数学, select score from studentscore hwere subject='英语' ) as
 英语, sum(score), avg(score) from studentscore group by stuid; --(错误查询)
(2) select stuid as 学号,name as 姓名,sum(case when subject=’语文’ then score else 0 end) as 语文,sum(case when subject=’数学’ then score else 0 end) as 数学,sum(case when subject=’英语’ then score else 0 end) as 英语,sum(score) as 总分,(sum(score)/count(*)) as 平均分 from stuscore group by stuid,name order by 总分 desc

 

--8.AVG():列出各门课程的平均成绩(要求显示字段:课程,平均成绩)
select subject, avg(score) from studentscore group by subject;

 

--9.Dense_Rank() or 存储过程:列出数学成绩的排名(要求显示字段:学号,姓名,成绩,排名)
(1)select stuid, name, score,count(0) as 排名 from studentscore where subject='数学' group by subject order by score;--(错误查询)
(2)declare @tmp table(pm int,name varchar(50),score int,stuid int)
insert into @tmp select null,name,score,stuid from stuscore where subject=’数学’ order by score desc
declare @id int
set @id=0;
update @tmp set @id=@id+1,pm=@id
select * from @tmp
(3)--oracle:
select DENSE_RANK () OVER(order by score desc) as row,name,subject,score,stuid from stuscore where subject=’数学’order by score desc
(4)--ms sql(最佳选择)
select (select count(*) from stuscore t1 where subject =’数学’ and t1.score>t2.score)+1 as row ,stuid,name,score from stuscore t2 where subject =’数学’ order by score desc

 


--10.Top 3:列出数学成绩在2-3名的学生(要求显示字段:学号,姓名,科目,成绩)
(1)select stuid, name, subject, score from studentscore where subject='数学' and count(0) as rank in ('2','3') group by suject
order  by score desc;--(错误查询)
-----先取出前三,然后从前三取出后二
(2)select t3.* from (select top 2 t2.*
     from
(select top 3 name,subject,score,stuid from stuscore where subject=’数学’order by score desc) t2 order by t2.score) t3
  order by t3.score

 

--11.存储过程: 求出李四的数学成绩的排名
(1)select
(select name, count(0) as rank from studentscore where  subject='数学' order by score desc ) from studentscore --(错误查询)
where name='李四'
(2)--局部变量用一个@,全局用两个@
declare @tmp table(pm int,name varchar(50),score int,stuid int)
insert into @tmp select null,name,score,stuid from stuscore where subject=’数学’ order by score desc
declare @id intset @id=0;
update @tmp set @id=@id+1,pm=@id
select * from @tmp where name=’李四’

 

--12.count(*): 统计如下:课程 不及格(0-59)个 良(60-80)个 优(81-100)个
(1)select subject, ( case when score <=59 then 1 else 0 end), (case wehn score>=60 and score<=80 then 1 else 0 end), count (case when score>=81 and score <=100 then 1 else 0 end) from studentscore group by subject;
(2)select subject, (select count(*) from stuscore where score<60 and subject=t1.subject) as 不及格,(select count(*) from stuscore where score between 60 and 80 and subject=t1.subject) as 良,(select count(*) from stuscore where score >80 and subject=t1.subject) as 优
from stuscore t1 group by subject

 

--13.统计如下:数学:张三(50分),李四(90分),王五(90分),赵六(76分)//Q3

 

declare @s varchar(1000)set @s=select @s =@s+’,’+name+'('+convert(varchar(10),score)+’分)’ from stuscore where subject=’数学’ set @s=stuff(@s,1,1,)
print ‘数学:’+@s
--删除指定长度的字符,并在指定的起点处插入另一组字符。
--STUFF ( character_expression , start , length ,character_expression ),i.e. SELECT STUFF('abcdef', 2, 3, 'ijklmn')
-->>aijklmnf

 

--14.计算科科及格的人的平均成绩
(1)select subject, average( select score from studentscore where score>=60 group by subject )
from studentscore group by subject;--(错误查询)
--查询平均成绩不小于60的人的平均成绩
(2)select distinct t1.stuid,t2.avgscore from stuscore t1,(select stuid,avg(score) as avgscore from stuscore group by stuid ) t2,(select stuid from stuscore where score<60 group by stuid) t3 where t1.stuid=t2.stuid and t1.stuid!=t3.stuid;
---大于60分的科目数为3
(3)select name,avg(score) as avgscore from stuscore s
where (select sum(case when i.score>=60 then 1 else 0 end) from stuscore i where i.name= s.name)=3
group by name

 

--5).not in or group by...... having: 查询出每门课都大于80 分的学生姓名

 

--name   kecheng   fenshu
 --张三      语文       81
 --张三      数学       75
 --李四      语文       76
 --李四      数学       90
 --王五      语文       81
 --王五      数学       100
 --王五      英语       90
(1)select name from studentscore where name in
 (select  (select name from studentscore where subject= '语文' and score >80) from
 studentscore where subject='数学' and score>80
 ) and subject='英语' and score>80; --(错误查询)
(2)
--查出分数小于80的名字, 剩下的就是都是大于80分的
 select distinct name from table where name not in (select distinct name from table where fenshu<=80)
(3)--查出所有最小分数大于80的人
 select name from table group by name having min(fenshu)>80
 --having 对已经分组的进行过滤
 
 
-------------五、SQL练习题2-------------

 

某班学生和考试成绩信息分别如下表Student和表Achievement所示:
ID Name
1  Jack
2  Marry
3  Rose
4  Bob
5  John
6         Betty
7         Robert
 

 

ID         Mark
1         90
2         96
3         88
4         86
5         83
6         85

 

表Student   , 表Achievement

 

其中ID为学生的编号,Name为姓名,Mark为成绩,请针对以下问题,写出相应的SQL语句:
--1、        请查询成绩>85分的学生的姓名;
select name from student where id in (select id from achievement where mark>85) and student.id=achievement.id ordre by student.id
select name from student where id not in (select id from achievement where mark<=85) and student.id=achievement.id order by student.id;

 

--2、        请查询成绩>=90分的人数;
select (case when mark>=90 then 1 else 0 end) from achievement;
select coun(*) form achievement where mark>=90;

 

--3、        Robert此次考试考了80分,但是成绩没能录入表中,请将其成绩添加进去;
insert into achievement(id,mark)  value('6','90');

 

--4、        请将Rose的成绩修改为87;
update achievement set mark='87' where id id=(select id from student where name='Rose') and student.id=achievement.id;
--5、        请删除Betty的记录;
delete from achievement where id=(select id from student where name='betty') and student.id=achievement.id;
delete from student where name='Betty';
 
-------------六、一些简单SQL-------------
select replace('jessica', 'ca','e');
select substring('abcdef',0,2);
select length('jessica');
select char(65);
select instr ('jessica','s');
select concat('Jessica','.','liu') as name;

 

select now();
select current_date()+current_time();

 

select rand();
select floor(4.7);
select floor(rand()*100);

 

show tables;
show columns from table1;

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值