SQL进阶1

CASE函数用法

语法:

1.Case...end 会生成一个新列,作用是判断你指定字段的值或者范围,然后得到一个用户自定义的对应的值

2.它并不会修改原始的表数据,而只是修改结果集的显示

3.case可以做等值判断,也可以做范围判断。

4.做等值判断的语法:

    case 字段或者表达式

      when 具体的值 then '用户自定义值'

      else 上面的when都不满足就满足else

    end

5.做等值判断的时候不能判断null值

    select StudentNo,StudentName,

    case ClassId+1 --当case后面接有字段或者表达式说这个case只能做行等值判断

     when 1 then '一期班'

     when 2 then '二期班'

      else '我不知道'

    end,--case会生成一个新列,所以如果Case..end后面还有其它列,就必须先使用,进行分割

    case email

     when  NULL  then '没有填写'

     else email

   end as 你要的列名

   from Student

case ..end做范围判断

语法:

  case --没有接任何的列名或者表达式

   when 表达式 then 值

   。。。。

   else  值  

  end

then后面的值的类型需要可以互换

when后面的表达式使用的字段可以是任意的,并不要求是同一个

  select StudentName,

  case

    when BornDate>'2000-1-1' then '小屁孩' --如果不满足这个when相当于隐藏一个条件转到下一个when

    when BornDate>'1990-1-1' then '小青年'

    when BornDate>'1980-1-1' then '小中年'

    when sex='男' then '他是男的'

  end,

  case

   when Email is null then '没有填写'

   else Email  

  end

   from Student

百分制转换为素质教育

  select StudentNo,

  case

   when StudentResult>=90 then 'A'

   when StudentResult>=80 then 'B'

   when StudentResult>=70 then 'C'

   when StudentResult>=60 then 'D'

   when StudentResult is  null then '没有考试'

   else  'E'

  end AS 成绩

   from Result

--IF ELSE--

1.也有多重和嵌套
2.没有{},用begin..end替代
3.if结构里面必须有语句做处理
4.没有所谓的true/false
5.()可以省略

if(1<>1)
  begin
  print 'aa'
  print 'bb'
  end
  go
 --计算office平均分数并输出,如果平均分数超过60分输出成绩最高的三个学生的成绩,否则输出后三名的学生

  declare @subjectName nvarchar(50)='office'--科目名称
  declare @subjectId int=(select SubjectId from Subject where SubjectName=@subjectName)--科目ID
  declare @avg int--平均分
  select @avg=(select AVG(StudentResult) from Result where SubjectId=@subjectId and studentresult is not null)
  if @avg>=60
   begin
   print '成绩不错。输入前三名:'
   select top 3 * from Result where SubjectId=@subjectId order by StudentResult desc
   end
  else
 begin
   print '成绩不好。输入后三名:'
   select top 3 * from Result where SubjectId=@subjectId order by StudentResult asc 
   end  

--WHILE循环--

1.不有写true/false

2.没有{},只有begin..and

3.可以嵌套

4.也可以在循环体写continue/break,continue可以中止当前这一次,继续下一次,break是跳出当前这一层循环

---计算1-100之间所有奇数的和--

     declare @i int=1

     declare @sum int=0

     while(@i<=100)

     begin

      if(@i%2!=0)

     begin

     set @sum+=@i

     end

      set @i+=1

     end

     print '和='+cast(@sum as char(4))
     go

     --如果office不及格的人超过半数(考试题出难了),则给每个人增加2分,循环加,直到不及格的人数少于一半。

     declare @subjectName nvarchar(50)='office'--科目名称

     declare @subejctId int=(select subjectId from Subject where SubjectName=@subjectName)--科目ID

     declare @totalNum int --总人数

     set @totalNum=(select COUNT(*) from Result where SubjectId=@subejctId)

     declare @unpassNum int---没有及格人数

     select @unpassNum =COUNT(*) from Result where SubjectId=@subejctId and StudentResult<70

     print @totalnum

     print @unpassnum

     while(@totalNum/2<@unpassNum)

     begin

     update Result set StudentResult+=5 where SubjectId=@subejctId and StudentResult <=95

     --再一次计算不及格人数

     select @unpassNum =COUNT(*) from Result where SubjectId=@subejctId and StudentResult<70

     end


     go

     declare @subjectName nvarchar(50)='office'--科目名称

     declare @subejctId int=(select subjectId from Subject where SubjectName=@subjectName)--科目ID

     declare @totalNum int --总人数

     set @totalNum=(select COUNT(*) from Result where SubjectId=@subejctId)

     declare @unpassNum int---没有及格人数

     select @unpassNum =COUNT(*) from Result where SubjectId=@subejctId and StudentResult<70

     print @totalnum

     print @unpassnum

     while(1=1)

     begin

     if((select COUNT(*) from Result where SubjectId=@subejctId and StudentResult<70)>@totalNum/2)

     update Result set StudentResult+=4 where SubjectId=@subejctId and StudentResult<=96

     else

     break

     end

---变量赋值

---局部变量--
语法
 declare @名称 类型=初始值

 declare @name varchar='aaaa' --如果字符串没有指定长度,那么长度就是1

 print @name

两种赋值方式:在sql中为变量赋值必须使用set/select,而不能直接使用 变量=值

set:侧重于直接给一个具体的值

select:侧重于通过查询赋值

go

--查询比林思大的学员信息

 select * from Student where BornDate<(select BornDate from Student where StudentName='林思')

go

 declare @time datetime

 --set后面如果是sql语句,那么必须接完整的 独立子查询

 set @time=(select  BornDate from Student where StudentName='林思')

 --使用select赋值,如果后面是sql语句,可以是独立子查询,也可以省略select关键字

 select @time=  BornDate from Student where StudentName='林思'

 print @time

使用set/select赋值的共同点

1.都能直接给值
2.如果后面的sql语句是一个完整Sql语句,那么两者没有任何的区别

区别:

 go
 declare @age int=100,@name varchar(50)='aaa'

1.set一次只能为一个变量赋值,而select可以一次为多个变量赋值

 set @age=20 ,@name='张三'

 select @age=20 ,@name='张三'

2.set进行赋值的时候如果sql语句返回多行一列值,那么:子查询返回的值不止一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。但是如果是select赋值且sql语句省略了select.那么会得到最后一个值

 set @name=(select StudentName from Student)

 select @name= StudentName from Student

3.如果sql语句返回null值,那么set会成为null值而select会保留原始值

 set @name=(select StudentName from Student where StudentNo=100)

 select @name= StudentName from Student where StudentNo=100

 print @name

 print @age

两种输出方式:

select:以结果集的方式输出

print :以文本形式输出,每一个print单独占据一行,且永远只能输出一个值,它是在服务器端输出的

 select * from Student

 print 'aa' +'bb'

查询参加最近一次“office”考试成绩最高分和最低分

 select MAX(StudentResult),MIN(StudentResult) 
   from Result
  where SubjectId=(select subjectid from subject where subjectname='office') 
     and ExamDate=(select max(examdate) from result where subjectid=(select subjectid from subject where subjectname='office'))

 declare @subjectname nvarchar(50)='office' --科目名称


go

 declare @subjectname nvarchar(50)='office' --科目名称

 declare @subjectId int --科目 ID

 set @subjectId=(select subjectid from subject where subjectname=@subjectname)

 declare @time datetime --最近一次考试日期

 select @time=MAX(examdate) from Result where SubjectId=@subjectId

查询

 select MAX(StudentResult),MIN(StudentResult) from Result where SubjectId=@subjectId and ExamDate=@time
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,285评论 0 10
  • 50个常用的sql语句Student(S#,Sname,Sage,Ssex) 学生表Course(C#,Cname...
    哈哈海阅读 1,224评论 0 7
  • 【清芳妖境】175 20180625 《NLP智沟通》课程开课前,老妈突然头晕。她第一时间想到的是让老爹带到附近的...
    清芳福田阅读 249评论 4 3
  • 冬天 孕育的秋 春天 萌发的秋 夏天 繁盛的秋 叶子落了 表象的秋
    起艺者阅读 137评论 0 0
  • 阅周海亮小说《分钟与千年》,文笔细润,介于随笔与小说之间,较之小说,多了些散文元素,较之散文,多了些小说氛围。都不...
    乔桥阅读 156评论 0 2