SQL进阶教程学习笔记

news/2024/11/30 3:49:38/

在学习《SQL进阶教程学习》的记录笔记,现学现用效率真的很高,带着问题学习,记忆会深很多很多。


  • CASE表达式

CASE表达式有简单CASE表达式(simple caseexpression)和搜索CASE表达式(searched case expression)两种写法。

    --简单CASE表达式CASE sexWHEN '1' THEN ’男’WHEN '2' THEN ’女’ELSE ’其他’ END--搜索CASE表达式CASE WHEN sex ='1'THEN’男’WHEN sex ='2'THEN’女’ELSE ’其他’ END

tips:

  1. 因为GROUP BY子句比SELECT语句先执行,所以在GROUP BY子句中引用在SELECT子句里定义的别称是不被允许的。
  • 用一条SQL语句进行不同条件的统计:

进行不同条件的统计是CASE表达式的著名用法之一。

  • 新手用WHERE子句进行条件分支,高手用SELECT子句进行条件分支:
    -- 男性人口SELECT pref_name,SUM(population)FROM PopTbl2WHERE sex ='1'GROUP BY pref_name;-- 女性人口SELECT pref_name,SUM(population)FROM PopTbl2WHERE sex ='2'GROUP BY pref_name;
    SELECT pref_name,--男性人口SUM( CASE WHEN sex ='1'THEN population ELSE 0 END) AS cnt_m,--女性人口SUM( CASE WHEN sex ='2'THEN population ELSE 0 END) AS cnt_fFROM  PopTbl2GROUP BY pref_name;
  • 用CHECK约束定义多个列的条件关系

  • 在UPDATE语句里进行条件分支
    --条件1UPDATE SalariesSET salary = salary * 0.9WHERE salary >= 300000;--条件2UPDATE SalariesSET salary = salary * 1.2WHERE salary >= 250000 AND salary < 280000;

两个UPDATE函数依次执行的话,可能会反复操作同一个数据,因此会造成错误。因此使用UPDATE与CASE函数结合,而且因为只需执行一次,所以速度也更快:

    --用CASE表达式写正确的更新操作UPDATE SalariesSET salary = CASE WHEN salary >= 300000THEN salary * 0.9WHEN salary >= 250000 AND salary < 280000THEN salary * 1.2ELSE salary END;
  • 主键值调换:
    --1.将a转换为中间值dUPDATE SomeTableSET p_key ='d'WHERE p_key ='a';--2.将b调换为aUPDATE SomeTableSET p_key ='a'WHERE p_key ='b';--3.将d调换为bUPDATE SomeTableSET p_key ='b'WHERE p_key ='d';

​​​​​​​没有必要执行3次UPDATE操作,因此可以用UPDATE结合CASE:

    --用CASE表达式调换主键值UPDATE SomeTableSET p_key = CASE WHEN p_key ='a'THEN 'b'WHEN p_key ='b'THEN 'a'ELSE p_key ENDWHERE p_key IN ('a', 'b');
  • 表之间的数据匹配
    --表的匹配:使用IN谓词SELECT course_name,CASE WHEN course_id IN(SELECT course_id FROM OpenCoursesWHERE month = 200706) THEN'○'ELSE'×'END AS "6月",CASE WHEN course_id IN(SELECT course_id FROM OpenCoursesWHERE month = 200707) THEN'○'ELSE'×'END AS "7月",CASE WHEN course_id IN(SELECT course_id FROM OpenCoursesWHERE month = 200708) THEN'○'ELSE'×'END  AS "8月"FROM CourseMaster;--表的匹配:使用EXISTS谓词SELECT CM.course_name,CASE WHEN EXISTS(SELECT course_id FROM OpenCourses OCWHERE month = 200706AND OC.course_id = CM.course_id) THEN'○'ELSE'×'END AS "6月",CASE WHEN EXISTS(SELECT course_id FROM OpenCourses OCWHERE month = 200707AND OC.course_id = CM.course_id) THEN'○'ELSE'×'END AS "7月",CASE WHEN EXISTS(SELECT course_id FROM OpenCourses OCWHERE month = 200708AND OC.course_id = CM.course_id) THEN'○'ELSE'×'END  AS "8月"FROM CourseMaster CM;

tips:

使用EXISTS时还要把两个表格的相同列表示出来。

  • 自连接
  • 排序

方法一、使用窗口函数:

    --排序:使用窗口函数SELECT name, price,RANK() OVER (ORDER BY price DESC) AS rank_1,DENSE_RANK() OVER (ORDER BY price DESC) AS rank_2FROM Products;

​​​​​​​tips:

  1. rank_1跳过了之后的位次,rank_2没有跳过,而是连续排序。

方法二、使用自连接:

    --排序从1开始。如果已出现相同位次,则跳过之后的位次SELECT P1.name,P1.price,(SELECT COUNT(P2.price)FROM Products P2WHERE P2.price > P1.price) + 1 AS rank_1FROM Products P1ORDER BY rank_1;

​​​​​​​

  • 三值逻辑和NULL:

二值逻辑:true、false

三值逻辑(three-valued logic):true、false、unknown

两种NULL分别指的是“未知”(unknown)和“不适用”(not applicable,inapplicable)。“未知”指的是“虽然现在不知道,但加上某些条件后就可以知道”;而“不适用”指的是“无论怎么努力都无法知道”。

三个真值之间的优先级顺序:

  1. AND的情况: false > unknown > true
  2. OR的情况: true > unknown > false

  • HAVING子句的力量:

SQL是一种基于“面向集合”思想设计的语言,同样具备这种设计思想的语言很少;最开始学习过了某种理念的语言后,心理上会形成思维定式,从而妨碍我们理解另一种理念的语言。

  • 寻找缺失的编号

  • EXISTS

  • 让SQL飞起来:

参数是子查询时,使用EXISTS代替IN

tips:

  1. 如果IN的参数是“1, 2, 3”这样的数值列表,一般还不需要特别注意。但是如果参数是子查询,那么就需要注意了。
  2. 但是从代码的可读性上来看,IN要比EXISTS好。使用IN时的代码看起来更加一目了然,易于理解。因此,如果确信使用IN也能快速获取结果,就没有必要非得改成EXISTS了。
  3. IN的参数是子查询时,数据库首先会执行子查询,然后将结果存储在一张临时的工作表里(内联视图),然后扫描整个视图。很多情况下这种做法都非常耗费资源。使用EXISTS的话,数据库不会生成临时的工作表

使用EXISTS时更快的原因有以下两个:

  1. 如果连接列(id)上建立了索引,那么查询Class_B时不用查实际的表,只需查索引就可以了。
  2. 如果使用EXISTS,那么只要查到一行数据满足条件就会终止查询,不用像使用IN时一样扫描全表。在这一点上NOT EXISTS也一样。

tips:

  1. 极值函数在统计时会把为NULL的数据排除掉。

(不定期更新。。。)


http://www.ppmy.cn/news/1201170.html

相关文章

SpringBoot基础(五)-- 引导类

引言: SpringBoot确实帮助我们减少了很多配置工作,下面说一下程序是如何运行的。目前程序运行的入口就是SpringBoot工程创建时自带的那个类了,带有main方法的那个类,运行这个类就可以启动SpringBoot工程的运行。 @SpringBootApplication public class SpringBootQu…

SQL注入之Sqli-labs第二关

本次注入sql-labs的第二关 1.进入第二关后&#xff0c;我们可以看到英语 please input the id as parameter with numeric value&#xff0c;请输入ID作为参数和数值。首先我们可以判断出这是一个GET请求作为注入点的题目&#xff0c;那么我们就需要去URL上拼接ID的值&#xff…

Hello Qt!

目录 1. 什么是Qt 2. Qt中的模块 3. 下载安装 4. QtCreator 4. Hello Qt 解释 .pro 解释 main.cpp 解释 mainwindow.ui 解释 mainwindow.h 解释 mainwindow.cpp 5. Qt 中的窗口类 5.1 基础窗口类 5.2 窗口的显示 6. Qt 的坐标体系 7. 内存回收 1. 什么是Qt 是一…

自动驾驶算法(七):基于遗传算法的路径规划(下)

目录 1 遗传选择 2 遗传交叉 3 遗传变异 4 结语 1 遗传选择 我们书接上回&#xff0c;我们完成了种群的初始化&#xff0c;将所有的种群放入了new_pop1中&#xff0c;这个new_pop1是一个&#xff08;种群大小 * 路径&#xff09;的一个矩阵&#xff0c;我们来看如何进行遗传…

文件夹批量改名:轻松实现文件夹随机重命名

无论是在我们的日常生活还是工作中&#xff0c;批量重命名文件夹是一项非常常见的任务。当我们需要整理或分类大量的文件时&#xff0c;往往需要对相应的文件夹进行重命名。然而&#xff0c;手动一个接一个地完成这个任务不仅会消耗大量的时间&#xff0c;还容易在重命名过程中…

llinux的更目录下的文件作用和举例

Linux是一种开源的操作系统&#xff0c;其文件系统采用了一种层次化的结构。在Linux文件系统中&#xff0c;最顶层的目录被称为根目录&#xff0c;也就是“/”&#xff08;斜杠&#xff09;。在根目录下&#xff0c;有很多文件和目录&#xff0c;它们各自有着不同的作用。本文将…

pytorch直线拟合

目录 1、数据分析 2、pytorch直线拟合 1、数据分析 直线拟合的前提条件通常包括以下几点&#xff1a; 存在线性关系&#xff1a;这是进行直线拟合的基础&#xff0c;数据点之间应该存在一种线性关系&#xff0c;即数据的分布可以用直线来近似描述。这种线性关系可以是数据点…

Go的错误处理

什么是错误&#xff1f; 错误表示程序中发生的任何异常情况。假设我们正在尝试打开一个文件&#xff0c;但该文件在文件系统中不存在。这是一种异常情况&#xff0c;表示为错误。 Go 中的错误是普通的旧值。就像任何其他内置类型&#xff08;例如 int、float64 等&#xff09…