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)两种写法  如下图所示

这两种写法的执行结果是相同的,“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

  • 转换成这种格式的结果

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

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

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语句的最下面。

同样的

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

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

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

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

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

两张题解

最后需要通过宿主语言或者应用程序将查询结果按列展开。如果使用UNION,只用一条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约束如下所示。

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

 在UPDATE语句里进行条件分支

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

 我们对表进行如下更新

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

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

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

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

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

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

值调换问题

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

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

表之间的数据匹配

 

我们使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/44117.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JAVA设计模式——23种设计模式详解

一、什么是设计模式&#x1f349; 设计模式&#xff08;Design pattern&#xff09; 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目…

MATLAB与ROS联合仿真——ROS环境搭建及相关准备工作(上)

本篇文章主要介绍在安装完ROS后&#xff0c;在进行MATLAB与ROS联合仿真之前&#xff0c;需要进行的一些环境搭建以及准备工作&#xff0c;主要分为 创建ROS工作空间及功能包、必备功能包安装、安装Gazebo11、导入实验功能包至工作空间、安装Visual_Studio_Code(选做)、常用便捷…

mac端数据库管理 Navicat Premium 15 for Mac v15.0.36

Navicat Premium 15是一款功能强大的数据库管理工具&#xff0c;由PremiumSoft CyberTech Ltd.开发。它提供了一个集成的界面&#xff0c;用于连接和管理多种不同类型的数据库&#xff0c;如MySQL、Oracle、SQL Server、PostgreSQL等。 Navicat Premium 15具有直观和用户友好的…

NFT和数字藏品的安全方案解析

一、NFT和数字藏品 01 NFT是什么&#xff1f; NFT 是Non-Fungible Tokens 的缩写&#xff0c;意思是不可互换的代币&#xff0c;它是相对于可互换的代币而言的。不可互换的代币也称为非同质代币。什么是可互换的代币&#xff1f;比如BTC&#xff08;比特币&#xff09;、ETH&…

SDN系统方法 | 5. 交换机操作系统

随着互联网和数据中心流量的爆炸式增长&#xff0c;SDN已经逐步取代静态路由交换设备成为构建网络的主流方式&#xff0c;本系列是免费电子书《Software-Defined Networks: A Systems Approach》的中文版&#xff0c;完整介绍了SDN的概念、原理、架构和实现方式。原文: Softwar…

react native 本地存储 AsyncStorage

An asynchronous, unencrypted, persistent, key-value storage system for React Native. Async Storage 只能用来储存字符串数据&#xff0c;所以为了去储存object类型的数据&#xff0c;得先进行序列化&#xff08;JSON.stringify()&#xff09;当你想要使用数据的时候&…

低代码:“提效降本”是如何炼成的

人们向往着从前车马慢的生活&#xff0c;可对于工厂而言&#xff0c;慢节奏如同噩梦。 目录 01、低代码的到来 02、让开发提效降本 03、结束语 在没有数字化以前的制造业&#xff0c;多个厂区之间的信息传递&#xff0c;例如采购单或者审批单&#xff0c;要用货车拉&#xff0c…

Keepalived热备、Keepalived+LVS、HAProxy监控及后端服务器健康检查、负载均衡调度器对比

day02 day02KeepAlived高可用集群配置高可用的web集群监控本机80端口&#xff0c;实现主备切换实现原理实施配置高可用、负载均衡的web集群配置高可用、负载均衡HAProxy配置haproxy负载均衡调度器比较LVS&#xff08;Linux Virtual Server&#xff09;NginxHAProxy KeepAlive…

iptables 防火墙

防火墙&#xff1a;隔离功能 部署在网络边缘或者主机边缘&#xff0c;在工作中&#xff0c;防火墙的主要作用&#xff0c;决定哪些数据可以被外网使用&#xff0c;以及哪些数据可以进入内网访问 主要工作在网络层 安全技术 1.入侵检测系统&#xff1a;检测出威胁&#xff0…

【后端面经】微服务构架 (1-3) | 熔断:熔断-恢复-熔断-恢复,抖来抖去怎么办?

文章目录 一、前置知识1、什么是熔断?2、什么是限流?3、什么是降级?4、怎么判断微服务出现了问题?A、指标有哪些?B、阈值如何选择?C、超过阈值之后,要不要持续一段时间才触发熔断?5、服务恢复正常二、面试环节1、面试准备2、面试基本思路三、总结 在微服务构架中…

【业务功能篇50】ObjectMapper-将java对象转为json字符串

ObjectMapper可以实现Java对象和json字符串间互相转换&#xff0c;我们经常用到的是它的Java对象转json字符串功能。 这里目的是 Java对象 json字符串相互转换 api 【json字符串转为Java对象&#xff1a;readValue(json字符串,类.class)】【Java对象转为json字符串&#xff1a…

WPF实战学习笔记09-创建工作单元

创建工作单元 添加包 Microsoft.EntityFrameworkCore.AutoHistory A plugin for Microsoft.EntityFrameworkCore to support automatically recording data changes history. Microsoft.EntityFrameworkCore.UnitOfWork A plugin for Microsoft.EntityFrameworkCore to suppor…

Python实战项目——旅游数据分析(四)

由于有之前的项目&#xff0c;所以今天我们直接开始&#xff0c;不做需求分析&#xff0c;还不会需求分析的可以看我之前的文章。Python实战项目——用户消费行为数据分析&#xff08;三&#xff09; 导入库 import numpy as np import pandas as pd import matplotlib.pyplo…

Canal深入调研

Canal深入调研 1.canal的设计 1.1 Canal的设计理念 canal的组件化设计非常好&#xff0c;有点类似于tomcat的设计。使用组合设计&#xff0c;依赖倒置&#xff0c;面向接口的设计。 说明&#xff1a; ​ server代表一个canal运行实例&#xff0c;对应于一个jvm ​ instance…

elasticsearch操作(命令方式)

说明&#xff1a;elasticsearch是目前最流行的搜索引擎&#xff0c;功能强大&#xff0c;非常受欢迎。特点是倒排索引&#xff0c;在海量数据的模糊查找领域&#xff0c;效率非常高。elasticsearch的安装和使用参考&#xff1a;http://t.csdn.cn/yJdZb。 本文介绍在es的索引库…

ajax/axios访问后端测试方法

文章目录 1、浏览器执行javascript方法GET请求POST请求 2、Postman测试工具GET请求POST请求 3、idea IDE提供的httpclient4、Apache JMeter 1、浏览器执行javascript方法 GET请求 http://localhost:6060/admin/get/123 POST请求 技巧&#xff1a;打开谷歌浏览器&#xff0c…

隧道安全监测解决方案

隧道安全监测 解决方案 一、监测目的 通过监控量测&#xff0c;实现信息化施工&#xff0c;不仅能及时掌握隧道实际的地质情况&#xff0c;掌握隧道围岩、支护衬砌结构的受力特征和变形情况&#xff0c;据此可以尽早发现塌方、大变形等灾害征兆&#xff0c;及时采取措施&…

使用ffmpeg合并视频遇到的坑

下面以Linux环境介绍为主 1.ffmpeg可执行命令不同的环境是不同的&#xff0c;Linux在执行命令前还需要授权。 2.合并视频命令&#xff1a; 主要命令: {} -f concat -auto_convert 0 -safe 0 -i {} -y -c:v copy 坑一&#xff1a;其中第一个花括号替换的是可执行命令所在的…

elementui全局给select option添加title属性

场景 有天边上的同事问了我一个问题&#xff0c;示例如下&#xff0c;有个数据特别长&#xff0c;导致下拉部分被横向撑大。希望在全局对所有的option进行处理&#xff0c;按照select的宽度&#xff0c;超出隐藏。 处理 方式一 第一眼看过去直接修改源码好了&#xff0c;修…

权智A133P 安卓10移植SPI转串WK2124驱动

硬件连接示意图 主控CPU通过SPI总线与WK2XXX芯相连接。WK2XXX控制4个UART的数据收发。 其中重要的参数有CS片选线和IRQ中断引脚。 LInux串口驱动框架 当WK2XXX驱动在内核注册成功后&#xff0c;会在/dev目录下面生成ttysWK0,ttysWK1,ttysWK2,ttysWK3节点。上层通过open,read,w…