sql进阶 之case表达式

这篇具有很好参考价值的文章主要介绍了sql进阶 之case表达式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

case表达式

CASE表达式是SQL里非常重要而且使用起来非常便利的技术,我们应该学会用它来描述条件分支。本节将通过行列转换、已有数据重分组(分类)、与约束的结合使用、针对聚合结果的条件分支等例题,来介绍CASE表达式的用法。标红即为他的作用

先读如下文章

明白mysql是行引擎

MySQL行列转换,理解 case when then else end as的用法_m0_72084056的博客-CSDN博客

case表达式的基本概念

        CASE表达式有简单CASE表达式(simple case expression)和搜索CASE表达式(searched case expression)两种写法  如下图所示

sql进阶 之case表达式,sql,数据库

这两种写法的执行结果是相同的,“sex”列(字段)如果是’1',那么结果为男;如果是’2',那么结果为女。简单CASE表达式正如其名,写法简单,但能实现的事情比较有限。简单CASE表达式能写的条件,搜索CASE表达式也能写,所以我们着重去看搜索CASE表达式

注:在发现为真的WHEN子句时,CASE表达式的真假值判断就会中止,而剩余的WHEN子句会被忽略。为了避免引起不必要的混乱,使用WHEN子句时要注意条件的排他性。

  •  剩余的WHEN子句被忽略的写法示例
  •     --例如,这样写的话,结果里不会出现“第二”
        CASE WHEN col_1 IN ('a', 'b') THEN’第一’
            WHEN col_1 IN ('a')     THEN’第二’
        ELSE ’其他’ END
    

 此外还需要注意

  1.  统一各分支返回的数据类型
  2.  不要忘了写END
  3.  养成写ELSE子句的习惯
  4. 与END不同,ELSE子句是可选的,不写也不会出错。不写ELSE子句时,CASE表达式的执行结果是NULL。但是不写可能会造成“语法没有错误,结果却不对”这种不易追查原因的麻烦,所以最好明确地写上ELSE子句(即便是在结果可以为NULL的情况下)。养成这样的习惯后,我们从代码上就可以清楚地看到这种条件下会生成NULL,而且将来代码有修改时也能减少失误。

将已有编号方式转换为新的方式并统计

在进行非定制化统计时,我们经常会遇到将已有编号方式转换为另外一种便于分析的方式并进行统计的需求。例如,现在有一张按照“‘1:北海道’、‘2:青森’、……、‘47:冲绳’”这种编号方式来统计都道府县[插图]人口的表,我们需要以东北、关东、九州等地区为单位来分组,并统计人口数量。具体来说,就是统计下表PopTbl中的内容,得出如右表“统计结果”所示的结果。

统计数据源表PopTbl

sql进阶 之case表达式,sql,数据库

  • 转换成这种格式的结果

sql进阶 之case表达式,sql,数据库

大家会怎么实现呢?定义一个包含“地区编号”列的视图是一种做法,但是这样一来,需要添加的列的数量将等同于统计对象的编号个数,而且很难动态地修改。而如果使用CASE表达式,则用如下所示的一条SQL语句就可以完成。为了便于理解,这里用县名(pref_name)代替编号作为GROUP BY的列。

sql进阶 之case表达式,sql,数据库

 各个语句的执行顺序(穿插的小点)

sql语句的书写顺序select--from--where--group by--having--order by 

与sql语句的书写顺序并不是一样的,而是按照下面的顺序来执行

from--where--group by--having--select--order by,

from:需要从哪个数据表检索数据

where:过滤表中数据的条件

group by:如何将上面过滤出的数据分组

having:对上面已经分组的数据进行过滤的条件  

select:查看结果集中的哪个列,或列的计算结果

order by :按照什么样的顺序来查看返回的数据

2.from后面的表关联,是自右向左解析的 

而where条件的解析顺序是自下而上的。 

也就是说,在写SQL文的时候,尽量把数据量大的表放在最右边来进行关联, 而把能筛选出大量数据的条件放在where语句的最下面。

同样的

sql进阶 之case表达式,sql,数据库

sql进阶 之case表达式,sql,数据库

个技巧非常好用。不过,必须在SELECT子句和GROUP BY子句这两处写一样的CASE表达式,这有点儿麻烦。后期需要修改的时候,很容易发生只改了这一处而忘掉改另一处的失误。

sql进阶 之case表达式,sql,数据库

不过有些数据库不支持,有些事不规范的,因为group是先于 select执行的 ,但是方便啊

用一条SQL语句进行不同条件的统计

进行不同条件的统计是CASE表达式的著名用法之一。例如,我们需要往存储各县人口数量的表PopTbl里添加上“性别”列,然后求按性别、县名汇总的人数。具体来说,就是统计表PopTbl2中的数据,然后求出如表“统计结果”所示的结果

sql进阶 之case表达式,sql,数据库

sql进阶 之case表达式,sql,数据库

从表中我们看到我们甚至更改了变得结构   我的理解这个case 表达式甚至能让你 查询出表中没有,但是可以总计欸的字段

两张题解

sql进阶 之case表达式,sql,数据库

最后需要通过宿主语言或者应用程序将查询结果按列展开。如果使用UNION,只用一条SQL语句就可以实现,但使用这种做法时,工作量并没有减少,SQL语句也会变得很长。而如果使用CASE表达式,下面这一条简单的SQL语句就可以搞定

sql进阶 之case表达式,sql,数据库

上面这段代码所做的是,分别统计每个县的“男性”(即’1')人数和“女性”(即’2')人数。也就是说,这里是将“行结构”的数据转换成了“列结构”的数据。除了SUM, COUNT、AVG等聚合函数也都可以用于将行结构的数据转换成列结构的数据。 

写一句代表我对你们的嘲笑哈哈哈哈哈

新手用WHERE子句进行条件分支,高手用SELECT子句进行条件分支。

用CHECK约束定义多个列的条件关系

首先啊,check和case 是非常般配的一对 嘻嘻嘻嘻哈哈哈哈 ,我一定是以很新的方式 学习

假设某公司规定“女性员工的工资必须在20万日元以下”,而在这个公司的人事表中,这条无理的规定是使用CHECK约束来描述的,代码如下所示

    CONSTRAINT check_salary CHECK
              ( CASE WHEN sex ='2'
                      THEN CASE WHEN salary <= 200000
                              THEN 1 ELSE 0 END
                      ELSE 1 END = 1 )

在这段代码里,CASE表达式被嵌入到CHECK约束里,描述了“如果是女性员工,则工资是20万日元以下”这个命题。在命题逻辑中,该命题是叫作蕴含式(conditional)的逻辑表达式,记作P→Q。

这里需要重点理解的是蕴含式和逻辑与(logical product)的区别。逻辑与也是一个逻辑表达式,意思是“P且Q”,记作P∧Q。用逻辑与改写的CHECK约束如下所示。sql进阶 之case表达式,sql,数据库

 结论是上述两个语句的结果是不一样的

sql进阶 之case表达式,sql,数据库

 在UPDATE语句里进行条件分支

举个例子 下面是一张工资表

sql进阶 之case表达式,sql,数据库

 我们对表进行如下更新

1.对当前工资为30万日元以上的员工,降薪10%。

2.对当前工资为25万日元以上且不满28万日元的员工,加薪20%。

如果我们对这些更新条件进行单独更新的话,就会出现问题 比如刚刚更新完了第一条,那么第条更新完的数据又符合第二条他又更新了怎么办,

这时候 就用case 语句来解决这种多条件更新的问题

这样只用更新一次效率也快

sql进阶 之case表达式,sql,数据库

需要注意的是,SQL语句最后一行的ELSE salary非常重要,必须写上。因为如果没有它,条件1和条件2都不满足的员工的工资就会被更新成NULL。这一点与CASE表达式的设计有关,在刚开始介绍CASE表达式的时候我们就已经了解到,如果CASE表达式里没有明确指定ELSE子句,执行结果会被默认地处理成ELSE NULL。现在大家明白笔者最开始强调使用CASE表达式时要习惯性地写上ELSE子句的理由了吧? 

值调换问题

sql进阶 之case表达式,sql,数据库

在mysql中主键值重复会出错好像会出错

但是呢也一般是因为表设计错误才需要调换值

表之间的数据匹配

sql进阶 之case表达式,sql,数据库

 sql进阶 之case表达式,sql,数据库

sql进阶 之case表达式,sql,数据库

我们使用in和exist 关键词去查找

    --表的匹配:使用IN谓词
    SELECT course_name,
          CASE WHEN course_id IN
                        (SELECT course_id FROM OpenCourses
                          WHERE month = 200706) THEN'○'
                ELSE'×'END AS "6月",
          CASE WHEN course_id IN
                        (SELECT course_id FROM OpenCourses
                          WHERE month = 200707) THEN'○'
                ELSE'×'END AS "7月",
          CASE WHEN course_id IN
                        (SELECT course_id FROM OpenCourses
                          WHERE month = 200708) THEN'○'
                ELSE'×'END  AS "8月"
      FROM CourseMaster;


    --表的匹配:使用EXISTS谓词
    SELECT CM.course_name,
          CASE WHEN EXISTS
                        (SELECT course_id FROM OpenCourses OC
                          WHERE month = 200706

                              AND OC.course_id = CM.course_id) THEN'○'
                  ELSE'×'END AS "6月",
              CASE WHEN EXISTS
                          (SELECT course_id FROM OpenCourses OC
                            WHERE month = 200707
                              AND OC.course_id = CM.course_id) THEN'○'
                  ELSE'×'END AS "7月",
              CASE WHEN EXISTS
                          (SELECT course_id FROM OpenCourses OC
                            WHERE month = 200708
                              AND OC.course_id = CM.course_id) THEN'○'
                  ELSE'×'END  AS "8月"
        FROM CourseMaster CM;

这样的查询没有进行聚合,因此也不需要排序,月份增加的时候仅修改SELECT子句就可以了,扩展性比较好。因为原来是有顺序的

无论使用IN还是EXISTS,得到的结果是一样的,但从性能方面来说,EXISTS更好。通过EXISTS进行的子查询能够用到“month, course_id”这样的主键索引,因此尤其是当表OpenCourses里数据比较多的时候更有优势

在CASE表达式中使用聚合函数

一句话就是case能代替having去办

肥春在这建议大家,一定要去练习,嘻嘻嘻嘻’

建议看看sql 进阶加成 mike文章来源地址https://www.toymoban.com/news/detail-606557.html

到了这里,关于sql进阶 之case表达式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c# 从零到精通 数据库 定义LINQ查询表达式,从数组中查找长度小于7的所有项

    c# 从零到精通 数据库 定义LINQ查询表达式,从数组中查找长度小于7的所有项 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQQuery { class Program { static void Main(string[] args) { //定义一个字符串数组 string[] strName = new string[] { “明日科技”,“C#编程词典”

    2024年02月10日
    浏览(38)
  • Case表达式

    在发现结果为真的WHEN子句时,CASE表达式的真假值判断会终止,剩余的WHEN子句会被忽略: 注意: 统一各分支返回的数据类型. 记得写end. 写else子句的习惯,否则执行结果默认处理为null. 将已有编号方式转换为新的方式并统计 下面给出的group by引用select中定义的别名,case写在group by违反

    2024年04月22日
    浏览(33)
  • 030、SQL语句之数据类型与表达式

    类型 存储空间 最小值(有符号/无符号) 最大值(有符号/无符号) TINYINT 1 -128 / 0 127 / 255 SMALLINT 2 -32768 / 0 32767 / 65535 MEDIUMINT 3 -8388608 / 0 8388607 / 16777215 INT 4 -2147483648 / 0 BIGINT 8 -9223372036854775808 / 0 9223372036854775807 / 18446744073709551615 注意unsigned: 不允许负数 用于精确数值:整数、小数或两

    2024年02月13日
    浏览(38)
  • Django笔记二十三之case、when操作条件表达式搜索、更新等操作

    本文首发于公众号:Hunter后端 原文链接:Django笔记二十三之条件表达式搜索、更新等操作 这一篇笔记将介绍条件表达式,就是如何在 model 的使用中根据不同的条件筛选数据返回。 这个操作类似于数据库中 if elif else 的逻辑。 以下是本篇笔记的目录: model 和数据准备 When 和

    2023年04月13日
    浏览(52)
  • String、反射、枚举、lambda表达式以及泛型进阶(数据结构系列16)

    目录 前言: 1. String 1.1 字符串常量池 1.1.1 创建对象的思考 1.1.2 字符串常量池(StringTable) 1.1.3 再谈String对象创建 1.1.4 intern方法 2. 反射 2.1 反射的定义 2.2 反射的用途 2.3 反射的基本信息 2.4 反射相关的类 2.4.1 Class类(反射机制的起源) 2.4.1.1 Class类中的相关方法 2.5 反

    2024年02月11日
    浏览(41)
  • 进阶JAVA篇- Lambda 表达式与 Lambda 表达式的省略规则

    目录         1.0 什么是 Lambda 表达式?         1.1 既然跟匿名内部类相关,先来回顾匿名内部类。          1.2 Lambda 表达式与匿名内部类之间的关系。         1.3 函数式接口         1.4 在具体代码中来操作一下         2.0 Lambda 表达式省略规则          Lambda 表达

    2024年02月08日
    浏览(44)
  • [Python进阶] 正则表达式介绍

    8.1.1 什么是正则表达式 字符是计算机软件处理文字时最基本的单位,一个字符可能是: 字母 数字 标点符号 空格 换行符 汉字 … 而字符串是由0个或多个字符组成的序列。文本也就是文字,字符串。说某个字符串匹配某个正则表达式,通常是指这个字符串里有一部分(或几部

    2024年01月21日
    浏览(35)
  • [Python进阶] 正则表达式的验证

    正则表达式的语法很令人头疼,即使对经常使用它的人来说也是如此。由于难于读写,容易出错,所以找一种工具对正则表达式进行测试是很有必要的。 8.2.1 本地验证 通过 Regex Tester 这款软件可以在本地对正则表达式进行验证,下面是Regex Tester运行时的截图: 分别将 源文本

    2024年01月20日
    浏览(32)
  • 【SQL-正则】利用正则表达式进行过滤操作(常用正则表达式)

    1、由数字、26个英文字母或者下划线组成的字符串 2、非负整数(正整数 + 0 ) 3、正整数 4、非正整数(负整数 + 0) 5、负整数 6、整数 7、非负浮点数(正浮点数 + 0) 8、正浮点数 9、非正浮点数(负浮点数 + 0) 10、负浮点数 11、浮点数 12、由26个英文字母组成的字符串 13、

    2024年02月12日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包