建站公司排名 软通网站群建设技术规范

pingmian/2026/1/25 10:50:30/文章来源:
建站公司排名 软通,网站群建设技术规范,中装建设集团股份有限公司,产品设计去哪里找工作-天池龙珠计划SQL训练营 SQL训练营页面地址#xff1a;https://tianchi.aliyun.com/specials/promotion/aicampsql 3.1 视图 我们先来看一个查询语句#xff08;仅做示例#xff0c;未提供相关数据#xff09; SELECT stu_name FROM view_students_info;单从表面上看起来…-天池龙珠计划SQL训练营 SQL训练营页面地址https://tianchi.aliyun.com/specials/promotion/aicampsql 3.1 视图 我们先来看一个查询语句仅做示例未提供相关数据 SELECT stu_name FROM view_students_info;单从表面上看起来这个语句是和正常的从数据表中查询数据是完全相同的但其实我们操作的是一个视图。所以从SQL的角度来说操作视图与操作表看起来是完全相同的那么为什么还会有视图的存在呢视图到底是什么视图与表有什么不同呢 3.1.1 什么是视图 视图是一个虚拟的表不同于直接操作数据表视图是依据SELECT语句来创建的会在下面具体介绍所以操作视图时会根据创建视图的SELECT语句生成一张虚拟表然后在这张虚拟表上做SQL操作。 3.1.2 视图与表有什么区别 《sql基础教程第2版**》用一句话非常凝练的概括了视图与表的区别—“是否保存了实际的数据”。所以视图并不是数据库真实存储的数据表它可以看作是一个窗口通过这个窗口我们可以看到数据库表中真实存在的数据。所以我们要区别视图和数据表的本质即视图是基于真实表的一张虚拟的表其数据来源均建立在真实表的基础上。 图片来源《sql基础教程第2版》 下面这句顺口溜也方便大家记忆视图与表的关系“视图不是表视图是虚表视图依赖于表”。 3.1.3 为什么会存在视图 那既然已经有数据表了为什么还需要视图呢主要有以下几点原因 通过定义视图可以将频繁使用的SELECT语句保存以提高效率。通过定义视图可以使用户看到的数据更加清晰。通过定义视图可以不对外公开数据表全部字段增强数据的保密性。通过定义视图可以降低数据的冗余。 3.1.4 如何创建视图 说了这么多视图与表的区别下面我们就一起来看一下如何创建视图吧。 创建视图的基本语法如下 CREATE VIEW 视图名称(列名1,列名2,...) AS SELECT语句其中SELECT 语句需要书写在 AS 关键字之后。 SELECT 语句中列的排列顺序和视图中列的排列顺序相同 SELECT 语句中的第 1 列就是视图中的第 1 列 SELECT 语句中的第 2 列就是视图中的第 2 列以此类推。而且视图的列名是在视图名称之后的列表中定义的。 需要注意的是视图名在数据库中需要是唯一的不能与其他视图和表重名。 视图不仅可以基于真实表我们也可以在视图的基础上继续创建视图。 图片来源《sql基础教程第2版》 虽然在视图上继续创建视图的语法没有错误但是我们还是应该尽量避免这种操作。这是因为对多数 DBMS 来说 多重视图会降低 SQL 的性能。 注意事项 需要注意的是在一般的DBMS中定义视图时不能使用ORDER BY语句。下面这样定义视图是错误的。 CREATE VIEW productsum (product_type, cnt_product) AS SELECT product_type, COUNT(*)FROM productGROUP BY product_typeORDER BY product_type;为什么不能使用 ORDER BY 子句呢这是因为视图和表一样数据行都是没有顺序的。 在 MySQL中视图的定义是允许使用 ORDER BY 语句的但是若从特定视图进行选择而该视图使用了自己的 ORDER BY 语句则视图定义中的 ORDER BY 将被忽略。 基于单表的视图 我们在product表的基础上创建一个视图如下 CREATE VIEW productsum (product_type, cnt_product) AS SELECT product_type, COUNT(*)FROM productGROUP BY product_type ;创建的视图如下图所示 基于多表的视图 为了学习多表视图我们再创建一张表相关代码如下 CREATE TABLE shop_product (shop_id CHAR(4) NOT NULL,shop_name VARCHAR(200) NOT NULL,product_id CHAR(4) NOT NULL,quantity INTEGER NOT NULL,PRIMARY KEY (shop_id, product_id)); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000A, 东京, 0001, 30); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000A, 东京, 0002, 50); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000A, 东京, 0003, 15); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0002, 30); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0003, 120); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0004, 20); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0006, 10); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0007, 40); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0003, 20); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0004, 50); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0006, 90); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0007, 70); INSERT INTO shop_product (shop_id, shop_name, product_id, quantity) VALUES (000D, 福冈, 0001, 100);我们在product表和shop_product表的基础上创建视图。 CREATE VIEW view_shop_product(product_type, sale_price, shop_name) AS SELECT product_type, sale_price, shop_nameFROM product,shop_productWHERE product.product_id shop_product.product_id;创建的视图如下图所示 我们可以在这个视图的基础上进行查询 SELECT sale_price, shop_nameFROM view_shop_productWHERE product_type 衣服;查询结果为 3.1.5 如何修改视图结构 修改视图结构的基本语法如下 ALTER VIEW 视图名 AS SELECT语句其中视图名在数据库中需要是唯一的不能与其他视图和表重名。 当然也可以通过将当前视图删除然后重新创建的方式达到修改的效果。对于数据库底层是不是也是这样操作的呢你可以自己探索一下。 修改视图 我们修改上方的productSum视图为 ALTER VIEW productSumASSELECT product_type, sale_priceFROM ProductWHERE regist_date 2009-09-11;此时productSum视图内容如下图所示 3.1.6 如何更新视图内容 因为视图是一个虚拟表所以对视图的操作就是对底层基础表的操作所以在修改时只有满足底层基本表的定义才能成功修改。 对于一个视图来说如果包含以下结构的任意一种都是不可以被更新的 聚合函数 SUM()、MIN()、MAX()、COUNT() 等。DISTINCT 关键字。GROUP BY 子句。HAVING 子句。UNION 或 UNION ALL 运算符。FROM 子句中包含多个表。 视图归根结底还是从表派生出来的因此如果原表可以更新那么 视图中的数据也可以更新。反之亦然如果视图发生了改变而原表没有进行相应更新的话就无法保证数据的一致性了。 更新视图 因为我们刚刚修改的productSum视图不包括以上的限制条件我们来尝试更新一下视图 UPDATE productsumSET sale_price 5000WHERE product_type 办公用品;此时我们再查看productSum视图可以发现数据已经更新了 此时观察原表也可以发现数据也被更新了 不知道大家看到这个结果会不会有疑问刚才修改视图的时候是设置product_type办公用品’的商品的sale_price5000为什么原表的数据只有一条做了修改呢 还是因为视图的定义视图只是原表的一个窗口所以它修改也只能修改透过窗口能看到的内容。 注意这里虽然修改成功了但是并不推荐这种使用方式。而且我们在创建视图时也尽量使用限制不允许通过视图来修改表 3.1.7 如何删除视图 删除视图的基本语法如下 DROP VIEW 视图名1 [ , 视图名2 …]注意需要有相应的权限才能成功删除。 删除视图 我们删除刚才创建的productSum视图 DROP VIEW productSum;如果我们继续操作这个视图的话就会提示当前操作的内容不存在。 3.2 子查询 我们先来看一个语句仅做示例未提供相关数据 SELECT stu_name FROM (SELECT stu_name, COUNT(*) AS stu_cntFROM students_infoGROUP BY stu_age) AS studentSum;这个语句看起来很好理解其中使用括号括起来的sql语句首先执行执行成功后再执行外面的sql语句。但是我们上一节提到的视图也是根据SELECT语句创建视图然后在这个基础上再进行查询。那么什么是子查询呢子查询和视图又有什么关系呢 3.2.1 什么是子查询 子查询指一个查询语句嵌套在另一个查询语句内部的查询这个特性从 MySQL 4.1 开始引入在 SELECT 子句中先计算子查询子查询结果作为外层另一个查询的过滤条件查询可以基于一个表或者多个表。 3.2.2 子查询和视图的关系 子查询就是将用来定义视图的 SELECT 语句直接用于 FROM 子句当中。其中AS studentSum可以看作是子查询的名称而且由于子查询是一次性的所以子查询不会像视图那样保存在存储介质中 而是在 SELECT 语句执行之后就消失了。 3.2.3 嵌套子查询 与在视图上再定义视图类似子查询也没有具体的限制例如我们可以这样 SELECT product_type, cnt_product FROM (SELECT *FROM (SELECT product_type, COUNT(*) AS cnt_productFROM product GROUP BY product_type) AS productsumWHERE cnt_product 4) AS productsum2;其中最内层的子查询我们将其命名为productSum这条语句根据product_type分组并查询个数第二层查询中将个数为4的商品查询出来最外层查询product_type和cnt_product两列。 虽然嵌套子查询可以查询出结果但是随着子查询嵌套的层数的叠加SQL语句不仅会难以理解而且执行效率也会很差所以要尽量避免这样的使用。 3.2.4 标量子查询 标量就是单一的意思那么标量子查询也就是单一的子查询那什么叫做单一的子查询呢 所谓单一就是要求我们执行的SQL语句只能返回一个值也就是要返回表中具体的某一行的某一列。例如我们有下面这样一张表 product_id | product_name | sale_price ----------------------------------- 0003 | 运动T恤 | 4000 0004 | 菜刀 | 3000 0005 | 高压锅 | 6800那么我们执行一次标量子查询后是要返回类似于“0004”“菜刀”这样的结果。 3.2.5 标量子查询有什么用 我们现在已经知道标量子查询可以返回一个值了那么它有什么作用呢 直接这样想可能会有些困难让我们看几个具体的需求 查询出销售单价高于平均销售单价的商品查询出注册日期最晚的那个商品 你有思路了吗 让我们看如何通过标量子查询语句查询出销售单价高于平均销售单价的商品。 SELECT product_id, product_name, sale_priceFROM productWHERE sale_price (SELECT AVG(sale_price) FROM product);上面的这条语句首先后半部分查询出product表中的平均售价前面的sql语句在根据WHERE条件挑选出合适的商品。 由于标量子查询的特性导致标量子查询不仅仅局限于 WHERE 子句中通常任何可以使用单一值的位置都可以使用。也就是说 能够使用常数或者列名的地方无论是 SELECT 子句、GROUP BY 子句、HAVING 子句还是 ORDER BY 子句几乎所有的地方都可以使用。 我们还可以这样使用标量子查询 SELECT product_id,product_name,sale_price,(SELECT AVG(sale_price)FROM product) AS avg_priceFROM product;你能猜到这段代码的运行结果是什么吗运行一下看看与你想象的结果是否一致。 3.2.6 关联子查询 什么是关联子查询 关联子查询既然包含关联两个字那么一定意味着查询与子查询之间存在着联系。这种联系是如何建立起来的呢 我们先看一个例子 SELECT product_type, product_name, sale_priceFROM product AS p1WHERE sale_price (SELECT AVG(sale_price)FROM product AS p2WHERE p1.product_type p2.product_typeGROUP BY product_type);你能理解这个例子在做什么操作么先来看一下这个例子的执行结果 通过上面的例子我们大概可以猜到吗关联子查询就是通过一些标志将内外两层的查询连接起来起到过滤数据的目的接下来我们就一起看一下关联子查询的具体内容吧。 关联子查询与子查询的联系 还记得我们之前的那个例子么查询出销售单价高于平均销售单价的商品这个例子的SQL语句如下 SELECT product_id, product_name, sale_priceFROM productWHERE sale_price (SELECT AVG(sale_price) FROM product);我们再来看一下这个需求选取出各商品种类中高于该商品种类的平均销售单价的商品。SQL语句如下 SELECT product_type, product_name, sale_priceFROM product ASp1WHERE sale_price (SELECT AVG(sale_price)FROM product ASp2WHERE p1.product_type p2.product_typeGROUP BY product_type);可以看出上面这两个语句的区别吗 在第二条SQL语句也就是关联子查询中我们将外面的product表标记为p1将内部的product设置为p2而且通过WHERE语句连接了两个查询。 但是如果刚接触的话一定会比较疑惑关联查询的执行过程这里有一个博客讲的比较清楚。在这里我们简要的概括为 首先执行不带WHERE的主查询根据主查询讯结果匹配product_type获取子查询结果将子查询结果再与主查询结合执行完整的SQL语句 在子查询中像标量子查询嵌套子查询或者关联子查询可以看作是子查询的一种操作方式即可。 小结 视图和子查询是数据库操作中较为基础的内容对于一些复杂的查询需要使用子查询加一些条件语句组合才能得到正确的结果。但是无论如何对于一个SQL语句来说都不应该设计的层数非常深且特别复杂不仅可读性差而且执行效率也难以保证所以尽量有简洁的语句来完成需要的功能。 练习题-第一部分 3.1 创建出满足下述三个条件的视图视图名称为 ViewPractice5_1。使用 product商品表作为参照表假设表中包含初始状态的 8 行数据。 条件 1销售单价大于等于 1000 日元。条件 2登记日期是 2009 年 9 月 20 日。条件 3包含商品名称、销售单价和登记日期三列。 对该视图执行 SELECT 语句的结果如下所示。 SELECT * FROM ViewPractice5_1;执行结果 product_name | sale_price | regist_date -------------------------------------- T恤衫 |   1000 | 2009-09-20 菜刀 | 3000 | 2009-09-20CREATE VIEW ViewPractice5_1 AS SELECT product_name , sale_price , regist_dateFROM product WHERE sale_price 1000AND regist_date 2009-09-20;3.2 向习题一中创建的视图 ViewPractice5_1 中插入如下数据会得到什么样的结果呢 INSERT INTO ViewPractice5_1 VALUES ( 刀子 , 300, 2009-11-02);答插入时会报错因为视图只有原表的三个字段而表的其他字段有非空约束所以插入三个字段不满足表约束。 3.3 请根据如下结果编写 SELECT 语句其中 sale_price_all 列为全部商品的平均销售单价。 product_id | product_name | product_type | sale_price | sale_price_all ------------------------------------------------------------------------ 0001 | T恤衫 | 衣服 | 1000 | 2097.5000000000000000 0002 | 打孔器 | 办公用品 | 500 | 2097.5000000000000000 0003 | 运动T恤 | 衣服 | 4000 | 2097.5000000000000000 0004 | 菜刀 | 厨房用具 | 3000 | 2097.5000000000000000 0005 | 高压锅 | 厨房用具 | 6800 | 2097.5000000000000000 0006 | 叉子 | 厨房用具 | 500 | 2097.5000000000000000 0007 | 擦菜板 | 厨房用具 | 880 | 2097.5000000000000000 0008 | 圆珠笔 | 办公用品 | 100 | 2097.5000000000000000SELECT product_id,product_name,product_type,sale_price,(SELECT AVG(sale_price) FROM product) AS sale_price_allFROM product;3.4 请根据习题一中的条件编写一条 SQL 语句创建一幅包含如下数据的视图名称为AvgPriceByType。 product_id | product_name | product_type | sale_price | avg_sale_price ------------------------------------------------------------------------ 0001 | T恤衫 | 衣服 | 1000 |2500.0000000000000000 0002 | 打孔器 | 办公用品 | 500 | 300.0000000000000000 0003 | 运动T恤 | 衣服 | 4000 |2500.0000000000000000 0004 | 菜刀 | 厨房用具 | 3000 |2795.0000000000000000 0005 | 高压锅 | 厨房用具 | 6800 |2795.0000000000000000 0006 | 叉子 | 厨房用具 | 500 |2795.0000000000000000 0007 | 擦菜板 | 厨房用具 | 880 |2795.0000000000000000 0008 | 圆珠笔 | 办公用品 | 100 | 300.0000000000000000提示其中的关键是 avg_sale_price 列。与习题三不同这里需要计算出的 是各商品种类的平均销售单价。这与使用关联子查询所得到的结果相同。 也就是说该列可以使用关联子查询进行创建。问题就是应该在什么地方使用这个关联子查询。 CREATE VIEW AvgPriceByType AS SELECT product_id,product_name,product_type,sale_price,(SELECT AVG(sale_price)FROM product p2WHERE p1.product_type p2.product_typeGROUP BY p1.product_type) AS avg_sale_price FROM product p1; -- 确认视图内容 SELECT * FROM AvgPriceByType;3.3 各种各样的函数 sql自带了各种各样的函数极大提高了sql语言的便利性。 所谓函数类似一个黑盒子你给它一个输入值它便按照预设的程序定义给出返回值输入值称为参数。 函数大致分为如下几类 算术函数 用来进行数值计算的函数字符串函数 用来进行字符串操作的函数日期函数 用来进行日期操作的函数转换函数 用来转换数据类型和值的函数聚合函数 用来进行数据聚合的函数 函数总个数超过200个不需要完全记住常用函数有 30~50 个其他不常用的函数使用时查阅文档即可。 3.3.1 算数函数 ** - * /**四则运算在之前的章节介绍过此处不再赘述。 为了演示其他的几个算数函数在此构造samplemath表 -- DDL 创建表 USE shop; DROP TABLE IF EXISTS samplemath; CREATE TABLE samplemath (m float(10,3), n INT, p INT);-- DML 插入数据 START TRANSACTION; -- 开始事务 INSERT INTO samplemath(m, n, p) VALUES (500, 0, NULL); INSERT INTO samplemath(m, n, p) VALUES (-180, 0, NULL); INSERT INTO samplemath(m, n, p) VALUES (NULL, NULL, NULL); INSERT INTO samplemath(m, n, p) VALUES (NULL, 7, 3); INSERT INTO samplemath(m, n, p) VALUES (NULL, 5, 2); INSERT INTO samplemath(m, n, p) VALUES (NULL, 4, NULL); INSERT INTO samplemath(m, n, p) VALUES (8, NULL, 3); INSERT INTO samplemath(m, n, p) VALUES (2.27, 1, NULL); INSERT INTO samplemath(m, n, p) VALUES (5.555,2, NULL); INSERT INTO samplemath(m, n, p) VALUES (NULL, 1, NULL); INSERT INTO samplemath(m, n, p) VALUES (8.76, NULL, NULL); COMMIT; -- 提交事务 -- 查询表内容 SELECT * FROM samplemath; ---------------------- | m | n | p | ---------------------- | 500.000 | 0 | NULL | | -180.000 | 0 | NULL | | NULL | NULL | NULL | | NULL | 7 | 3 | | NULL | 5 | 2 | | NULL | 4 | NULL | | 8.000 | NULL | 3 | | 2.270 | 1 | NULL | | 5.555 | 2 | NULL | | NULL | 1 | NULL | | 8.760 | NULL | NULL | ---------------------- 11 rows in set (0.00 sec)ABS – 绝对值 语法ABS( 数值 ) ABS 函数用于计算一个数字的绝对值表示一个数到原点的距离。 当 ABS 函数的参数为NULL时返回值也是NULL。 MOD – 求余数 语法MOD( 被除数除数 ) MOD 是计算除法余数求余的函数是 modulo 的缩写。小数没有余数的概念只能对整数列求余数。 注意主流的 DBMS 都支持 MOD 函数只有SQL Server 不支持该函数其使用**%**符号来计算余数。 ROUND – 四舍五入 语法ROUND( 对象数值保留小数的位数 ) ROUND 函数用来进行四舍五入操作。 注意当参数 保留小数的位数 为变量时可能会遇到错误请谨慎使用变量。 SELECT m, ABS(m)ASabs_col , n, p, MOD(n, p) AS mod_col, ROUND(m,1)ASround_colS FROM samplemath; --------------------------------------------------- | m | abs_col | n | p | mod_col | round_col | --------------------------------------------------- | 500.000 | 500.000 | 0 | NULL | NULL | 500.0 | | -180.000 | 180.000 | 0 | NULL | NULL | -180.0 | | NULL | NULL | NULL | NULL | NULL | NULL | | NULL | NULL | 7 | 3 | 1 | NULL | | NULL | NULL | 5 | 2 | 1 | NULL | | NULL | NULL | 4 | NULL | NULL | NULL | | 8.000 | 8.000 | NULL | 3 | NULL | 8.0 | | 2.270 | 2.270 | 1 | NULL | NULL | 2.3 | | 5.555 | 5.555 | 2 | NULL | NULL | 5.6 | | NULL | NULL | 1 | NULL | NULL | NULL | | 8.760 | 8.760 | NULL | NULL | NULL | 8.8 | --------------------------------------------------- 11 rows in set (0.08 sec)3.3.2 字符串函数 字符串函数也经常被使用为了学习字符串函数在此我们构造samplestr表。 -- DDL 创建表 USE shop; DROP TABLE IF EXISTS samplestr; CREATE TABLE samplestr (str1 VARCHAR (40), str2 VARCHAR (40), str3 VARCHAR (40) ); -- DML插入数据 START TRANSACTION; INSERT INTO samplestr (str1, str2, str3) VALUES (opx, rt, NULL); INSERT INTO samplestr (str1, str2, str3) VALUES (abc, def, NULL); INSERT INTO samplestr (str1, str2, str3) VALUES (太阳, 月亮, 火星); INSERT INTO samplestr (str1, str2, str3) VALUES (aaa, NULL, NULL); INSERT INTO samplestr (str1, str2, str3) VALUES (NULL, xyz, NULL); INSERT INTO samplestr (str1, str2, str3) VALUES (!#$%, NULL, NULL); INSERT INTO samplestr (str1, str2, str3) VALUES (ABC, NULL, NULL); INSERT INTO samplestr (str1, str2, str3) VALUES (aBC, NULL, NULL); INSERT INTO samplestr (str1, str2, str3) VALUES (abc哈哈, abc, ABC); INSERT INTO samplestr (str1, str2, str3) VALUES (abcdefabc, abc, ABC); INSERT INTO samplestr (str1, str2, str3) VALUES (micmic, i, I); COMMIT; -- 确认表中的内容 SELECT * FROM samplestr; ----------------------- | str1 | str2 | str3 | ----------------------- | opx | rt | NULL | | abc | def | NULL | | 太阳 | 月亮 | 火星 | | aaa | NULL | NULL | | NULL | xyz | NULL | | !#$% | NULL | NULL | | ABC | NULL | NULL | | aBC | NULL | NULL | | abc哈哈 | abc | ABC | | abcdefabc | abc | ABC | | micmic | i | I | ----------------------- 11 rows in set (0.00 sec)CONCAT – 拼接 语法CONCAT(str1, str2, str3) MySQL中使用 CONCAT 函数进行拼接。 LENGTH – 字符串长度 语法LENGTH( 字符串 ) LOWER – 小写转换 LOWER 函数只能针对英文字母使用它会将参数中的字符串全都转换为小写。该函数不适用于英文字母以外的场合不影响原本就是小写的字符。 类似的 UPPER 函数用于大写转换。 REPLACE – 字符串的替换 语法REPLACE( 对象字符串替换前的字符串替换后的字符串 ) SUBSTRING – 字符串的截取 语法SUBSTRING 对象字符串 FROM 截取的起始位置 FOR 截取的字符数 使用 SUBSTRING 函数 可以截取出字符串中的一部分字符串。截取的起始位置从字符串最左侧开始计算索引值起始为1。 扩展内容SUBSTRING_INDEX – 字符串按索引截取 语法SUBSTRING_INDEX (原始字符串 分隔符n) 该函数用来获取原始字符串按照分隔符分割后第 n 个分隔符之前或之后的子字符串支持正向和反向索引索引起始值分别为 1 和 -1。 SELECT SUBSTRING_INDEX(www.mysql.com, ., 2); ------------------------------------------ | SUBSTRING_INDEX(www.mysql.com, ., 2) | ------------------------------------------ | www.mysql | ------------------------------------------ 1 row in set (0.00 sec) SELECT SUBSTRING_INDEX(www.mysql.com, ., -2); ------------------------------------------- | SUBSTRING_INDEX(www.mysql.com, ., -2) | ------------------------------------------- | mysql.com | ------------------------------------------- 1 row in set (0.00 sec)获取第1个元素比较容易获取第2个元素/第n个元素可以采用二次拆分的写法。 SELECT SUBSTRING_INDEX(www.mysql.com, ., 1); ------------------------------------------ | SUBSTRING_INDEX(www.mysql.com, ., 1) | ------------------------------------------ | www | ------------------------------------------ 1 row in set (0.00 sec) SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(www.mysql.com, ., 2), ., -1); -------------------------------------------------------------------- | SUBSTRING_INDEX(SUBSTRING_INDEX(www.mysql.com, ., 2), ., -1) | -------------------------------------------------------------------- | mysql | -------------------------------------------------------------------- 1 row in set (0.00 sec)3.3.3 日期函数 不同DBMS的日期函数语法各有不同本课程介绍一些被标准 SQL 承认的可以应用于绝大多数 DBMS 的函数。特定DBMS的日期函数查阅文档即可。 CURRENT_DATE – 获取当前日期 SELECT CURRENT_DATE; -------------- | CURRENT_DATE | -------------- | 2020-08-08 | -------------- 1 row in set (0.00 sec)CURRENT_TIME – 当前时间 SELECT CURRENT_TIME; -------------- | CURRENT_TIME | -------------- | 17:26:09 | -------------- 1 row in set (0.00 sec)CURRENT_TIMESTAMP – 当前日期和时间 SELECT CURRENT_TIMESTAMP; --------------------- | CURRENT_TIMESTAMP | --------------------- | 2020-08-08 17:27:07 | --------------------- 1 row in set (0.00 sec)EXTRACT – 截取日期元素 语法EXTRACT(日期元素 FROM 日期) 使用 EXTRACT 函数可以截取出日期数据中的一部分例如“年” “月”或者“小时”“秒”等。该函数的返回值并不是日期类型而是数值类型 SELECT CURRENT_TIMESTAMP as now, EXTRACT(YEAR FROM CURRENT_TIMESTAMP) AS year, EXTRACT(MONTH FROM CURRENT_TIMESTAMP) AS month, EXTRACT(DAY FROM CURRENT_TIMESTAMP) AS day, EXTRACT(HOUR FROM CURRENT_TIMESTAMP) AS hour, EXTRACT(MINUTE FROM CURRENT_TIMESTAMP) AS MINute, EXTRACT(SECOND FROM CURRENT_TIMESTAMP) AS second; -------------------------------------------------------------- | now | year | month | day | hour | MINute | second | -------------------------------------------------------------- | 2020-08-08 17:34:38 | 2020 | 8 | 8 | 17 | 34 | 38 | -------------------------------------------------------------- 1 row in set (0.00 sec)3.3.4 转换函数 “转换”这个词的含义非常广泛在 SQL 中主要有两层意思一是数据类型的转换简称为类型转换在英语中称为cast另一层意思是值的转换。 CAST – 类型转换 语法CAST转换前的值 AS 想要转换的数据类型 -- 将字符串类型转换为数值类型 SELECT CAST(0001 AS SIGNED INTEGER) AS int_col; --------- | int_col | --------- | 1 | --------- 1 row in set (0.00 sec) -- 将字符串类型转换为日期类型 SELECT CAST(2009-12-14 AS DATE) AS date_col; ------------ | date_col | ------------ | 2009-12-14 | ------------ 1 row in set (0.00 sec)COALESCE – 将NULL转换为其他值 语法COALESCE(数据1数据2数据3……) COALESCE 是 SQL 特有的函数。该函数会返回可变参数 A 中左侧开始第 1个不是NULL的值。参数个数是可变的因此可以根据需要无限增加。 在 SQL 语句中将 NULL 转换为其他值时就会用到转换函数。 SELECT COALESCE(NULL, 11) AS col_1, COALESCE(NULL, hello world, NULL) AS col_2, COALESCE(NULL, NULL, 2020-11-01) AS col_3; -------------------------------- | col_1 | col_2 | col_3 | -------------------------------- | 11 | hello world | 2020-11-01 | -------------------------------- 1 row in set (0.00 sec)3.4 谓词 3.4.1 什么是谓词 谓词就是返回值为真值的函数。包括TRUE / FALSE / UNKNOWN。 谓词主要有以下几个 LIKEBETWEENIS NULL、IS NOT NULLINEXISTS 3.4.2 LIKE谓词 – 用于字符串的部分一致查询 当需要进行字符串的部分一致查询时需要使用该谓词。 部分一致大体可以分为前方一致、中间一致和后方一致三种类型。 首先我们来创建一张表 -- DDL 创建表 CREATE TABLE samplelike ( strcol VARCHAR(6) NOT NULL, PRIMARY KEY (strcol) samplelike); -- DML 插入数据 START TRANSACTION; -- 开始事务 INSERT INTO samplelike (strcol) VALUES (abcddd); INSERT INTO samplelike (strcol) VALUES (dddabc); INSERT INTO samplelike (strcol) VALUES (abdddc); INSERT INTO samplelike (strcol) VALUES (abcdd); INSERT INTO samplelike (strcol) VALUES (ddabc); INSERT INTO samplelike (strcol) VALUES (abddc); COMMIT; -- 提交事务 SELECT * FROM samplelike; -------- | strcol | -------- | abcdd | | abcddd | | abddc | | abdddc | | ddabc | | dddabc | -------- 6 rows in set (0.00 sec)前方一致选取出“dddabc” 前方一致即作为查询条件的字符串这里是“ddd”与查询对象字符串起始部分相同。 SELECT * FROM samplelike WHERE strcol LIKE ddd%; -------- | strcol | -------- | dddabc | -------- 1 row in set (0.00 sec)其中的**%**是代表“零个或多个任意字符串”的特殊符号本例中代表“以ddd开头的所有字符串”。 中间一致选取出“abcddd”,“dddabc”,“abdddc” 中间一致即查询对象字符串中含有作为查询条件的字符串无论该字符串出现在对象字 符串的最后还是中间都没有关系。 SELECT * FROM samplelike WHERE strcol LIKE %ddd%; -------- | strcol | -------- | abcddd | | abdddc | | dddabc | -------- 3 rows in set (0.00 sec)后方一致选取出“abcddd“ 后方一致即作为查询条件的字符串这里是“ddd”与查询对象字符串的末尾部分相同。 SELECT * FROM samplelike WHERE strcol LIKE %ddd; -------- | strcol | -------- | abcddd | -------- 1 row in set (0.00 sec)综合如上三种类型的查询可以看出查询条件最宽松也就是能够取得最多记录的是中间一致。这是因为它同时包含前方一致和后方一致的查询结果。 **_**下划线匹配任意 1 个字符 使用 _下划线来代替 %与 % 不同的是它代表了“任意 1 个字符”。 SELECT * FROM samplelike WHERE strcol LIKE abc__; -------- | strcol | -------- | abcdd | -------- 1 row in set (0.00 sec)3.4.3 BETWEEN谓词 – 用于范围查询 使用 BETWEEN 可以进行范围查询。该谓词与其他谓词或者函数的不同之处在于它使用了 3 个参数。 -- 选取销售单价为100 1000元的商品 SELECT product_name, sale_price FROM product WHERE sale_price BETWEEN 100 AND 1000; -------------------------- | product_name | sale_price | -------------------------- | T恤 | 1000 | | 打孔器 | 500 | | 叉子 | 500 | | 擦菜板 | 880 | | 圆珠笔 | 100 | -------------------------- 5 rows in set (0.00 sec)BETWEEN 的特点就是结果中会包含 100 和 1000 这两个临界值也就是闭区间。如果不想让结果中包含临界值那就必须使用 和 。 SELECT product_name, sale_price FROM product WHERE sale_price 100 AND sale_price 1000; -------------------------- | product_name | sale_price | -------------------------- | 打孔器 | 500 | | 叉子 | 500 | | 擦菜板 | 880 | -------------------------- 3 rows in set (0.00 sec)3.4.4 IS NULL、 IS NOT NULL – 用于判断是否为NULL 为了选取出某些值为 NULL 的列的数据不能使用 而只能使用特定的谓词IS NULL。 SELECT product_name, purchase_price FROM product WHERE purchase_price IS NULL; ------------------------------ | product_name | purchase_price | ------------------------------ | 叉子 | NULL | | 圆珠笔 | NULL | ------------------------------ 2 rows in set (0.00 sec)与此相反想要选取 NULL 以外的数据时需要使用IS NOT NULL。 SELECT product_name, purchase_price FROM product WHERE purchase_price IS NOT NULL; ------------------------------ | product_name | purchase_price | ------------------------------ | T恤 | 500 | | 打孔器 | 320 | | 运动T恤 | 2800 | | 菜刀 | 2800 | | 高压锅 | 5000 | | 擦菜板 | 790 | ------------------------------ 6 rows in set (0.00 sec)3.4.5 IN谓词 – OR的简便用法 多个查询条件取并集时可以选择使用or语句。 -- 通过OR指定多个进货单价进行查询 SELECT product_name, purchase_price FROM product WHERE purchase_price 320 OR purchase_price 500 OR purchase_price 5000; ------------------------------ | product_name | purchase_price | ------------------------------ | T恤 | 500 | | 打孔器 | 320 | | 高压锅 | 5000 | ------------------------------ 3 rows in set (0.00 sec)虽然上述方法没有问题但还是存在一点不足之处那就是随着希望选取的对象越来越多 SQL 语句也会越来越长阅读起来也会越来越困难。这时 我们就可以使用IN 谓词 IN(值1, 值2, 值3, …)来替换上述 SQL 语句。 SELECT product_name, purchase_price FROM product WHERE purchase_price IN (320, 500, 5000); ------------------------------ | product_name | purchase_price | ------------------------------ | T恤 | 500 | | 打孔器 | 320 | | 高压锅 | 5000 | ------------------------------ 3 rows in set (0.00 sec)上述语句简洁了很多可读性大幅提高。 反之希望选取出“进货单价不是 320 元、 500 元、 5000 元”的商品时可以使用否定形式NOT IN来实现。 SELECT product_name, purchase_price FROM product WHERE purchase_price NOT IN (320, 500, 5000); ------------------------------ | product_name | purchase_price | ------------------------------ | 运动T恤 | 2800 | | 菜刀 | 2800 | | 擦菜板 | 790 | ------------------------------ 3 rows in set (0.00 sec)需要注意的是在使用IN 和 NOT IN 时是无法选取出NULL数据的。 实际结果也是如此上述两组结果中都不包含进货单价为 NULL 的叉子和圆珠笔。 NULL 只能使用 IS NULL 和 IS NOT NULL 来进行判断。 3.4.6 使用子查询作为IN谓词的参数 IN和子查询 IN 谓词NOT IN 谓词具有其他谓词所没有的用法那就是可以使用子查询作为其参数。我们已经在 5-2 节中学习过了子查询就是 SQL内部生成的表因此也可以说“能够将表作为 IN 的参数”。同理我们还可以说“能够将视图作为 IN 的参数”。 在此我们创建一张新表shopproduct显示出哪些商店销售哪些商品。 -- DDL 创建表 DROP TABLE IF EXISTS shopproduct; CREATE TABLE shopproduct ( shop_id CHAR(4) NOT NULL,shop_name VARCHAR(200) NOT NULL, product_id CHAR(4) NOT NULL,quantity INTEGER NOT NULL, PRIMARY KEY (shop_id, product_id) -- 指定主键 ); -- DML 插入数据 START TRANSACTION; -- 开始事务 INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000A, 东京, 0001, 30); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000A, 东京, 0002, 50); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000A, 东京, 0003, 15); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0002, 30); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0003, 120); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0004, 20); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0006, 10); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000B, 名古屋, 0007, 40); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0003, 20); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0004, 50); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0006, 90); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000C, 大阪, 0007, 70); INSERT INTO shopproduct (shop_id, shop_name, product_id, quantity) VALUES (000D, 福冈, 0001, 100); COMMIT; -- 提交事务 SELECT * FROM shopproduct; ------------------------------------------ | shop_id | shop_name | product_id | quantity | ------------------------------------------ | 000A | 东京 | 0001 | 30 | | 000A | 东京 | 0002 | 50 | | 000A | 东京 | 0003 | 15 | | 000B | 名古屋 | 0002 | 30 | | 000B | 名古屋 | 0003 | 120 | | 000B | 名古屋 | 0004 | 20 | | 000B | 名古屋 | 0006 | 10 | | 000B | 名古屋 | 0007 | 40 | | 000C | 大阪 | 0003 | 20 | | 000C | 大阪 | 0004 | 50 | | 000C | 大阪 | 0006 | 90 | | 000C | 大阪 | 0007 | 70 | | 000D | 福冈 | 0001 | 100 | ------------------------------------------ 13 rows in set (0.00 sec)由于单独使用商店编号shop_id或者商品编号product_id不能区分表中每一行数据 因此指定了 2 列作为主键primary key对商店和商品进行组合用来唯一确定每一行数据。 假设我么需要取出大阪在售商品的销售单价该如何实现呢 第一步取出大阪门店的在售商品 product_id ; 第二步取出大阪门店在售商品的销售单价 sale_price -- step1取出大阪门店的在售商品 product_id SELECT product_id FROM shopproduct WHERE shop_id 000C; ------------ | product_id | ------------ | 0003 | | 0004 | | 0006 | | 0007 | ------------ 4 rows in set (0.00 sec)上述语句取出了大阪门店的在售商品编号接下来我么可以使用上述语句作为第二步的查询条件来使用了。 -- step2取出大阪门店在售商品的销售单价 sale_price SELECT product_name, sale_price FROM product WHERE product_id IN (SELECT product_idFROM shopproductWHERE shop_id 000C); -------------------------- | product_name | sale_price | -------------------------- | 运动T恤 | 4000 | | 菜刀 | 3000 | | 叉子 | 500 | | 擦菜板 | 880 | -------------------------- 4 rows in set (0.00 sec)根据第5章学习的知识子查询是从最内层开始执行的由内而外因此上述语句的子查询执行之后sql 展开成下面的语句 -- 子查询展开后的结果 SELECT product_name, sale_price FROM product WHERE product_id IN (0003, 0004, 0006, 0007); -------------------------- | product_name | sale_price | -------------------------- | 运动T恤 | 4000 | | 菜刀 | 3000 | | 叉子 | 500 | | 擦菜板 | 880 | -------------------------- 4 rows in set (0.00 sec)可以看到子查询转换之后变为 in 谓词用法你理解了吗 或者你会疑惑既然 in 谓词也能实现那为什么还要使用子查询呢这里给出两点原因 ①实际生活中某个门店的在售商品是不断变化的使用 in 谓词就需要经常更新 sql 语句降低了效率提高了维护成本 ②实际上某个门店的在售商品可能有成百上千个手工维护在售商品编号真是个大工程。 使用子查询即可保持 sql 语句不变极大提高了程序的可维护性这是系统开发中需要重点考虑的内容。 NOT IN和子查询 NOT IN 同样支持子查询作为参数用法和 in 完全一样。 -- NOT IN 使用子查询作为参数取出未在大阪门店销售的商品的销售单价 SELECT product_name, sale_priceFROM productWHERE product_id NOT IN (SELECT product_idFROM shopproductWHERE shop_id 000A); -------------------------- | product_name | sale_price | -------------------------- | 菜刀 | 3000 | | 高压锅 | 6800 | | 叉子 | 500 | | 擦菜板 | 880 | | 圆珠笔 | 100 | -------------------------- 5 rows in set (0.00 sec)3.4.7 EXIST 谓词 EXIST 谓词的用法理解起来有些难度。 ① EXIST 的使用方法与之前的都不相同 ② 语法理解起来比较困难 ③ 实际上即使不使用 EXIST基本上也都可以使用 IN或者 NOT IN来代替 这么说的话还有学习 EXIST 谓词的必要吗答案是肯定的因为一旦能够熟练使用 EXIST 谓词就能体会到它极大的便利性。 不过你不用过于担心本课程介绍一些基本用法日后学习时可以多多留意 EXIST 谓词的用法以期能够在达到 SQL 中级水平时掌握此用法。 EXIST谓词的使用方法 谓词的作用就是 “判断是否存在满足某种条件的记录”。 如果存在这样的记录就返回真TRUE如果不存在就返回假FALSE。 EXIST存在谓词的主语是“记录”。 我们继续以 IN和子查询 中的示例使用 EXIST 选取出大阪门店在售商品的销售单价。 SELECT product_name, sale_priceFROM product AS pWHERE EXISTS (SELECT *FROM shopproduct AS spWHERE sp.shop_id 000CAND sp.product_id p.product_id); -------------------------- | product_name | sale_price | -------------------------- | 运动T恤 | 4000 | | 菜刀 | 3000 | | 叉子 | 500 | | 擦菜板 | 880 | -------------------------- 4 rows in set (0.00 sec)EXIST的参数 之前我们学过的谓词基本上都是像“列 LIKE 字符串”或者“ 列 BETWEEN 值 1 AND 值 2”这样需要指定 2 个以上的参数而 EXIST 的左侧并没有任何参数。因为 EXIST 是只有 1 个参数的谓词。 所以EXIST 只需要在右侧书写 1 个参数该参数通常都会是一个子查询。 (SELECT *FROM shopproduct AS spWHERE sp.shop_id 000CAND sp.product_id p.product_id)上面这样的子查询就是唯一的参数。确切地说由于通过条件“SP.product_id P.product_id”将 product 表和 shopproduct表进行了联接因此作为参数的是关联子查询。 EXIST 通常会使用关联子查询作为参数。 子查询中的SELECT * 由于 EXIST 只关心记录是否存在因此返回哪些列都没有关系。 EXIST 只会判断是否存在满足子查询中 WHERE 子句指定的条件“商店编号shop_id为 ‘000C’商品product表和商店 商品shopproduct表中商品编号product_id相同”的记录只有存在这样的记录时才返回真TRUE。 因此使用下面的查询语句查询结果也不会发生变化。 SELECT product_name, sale_priceFROM product AS pWHERE EXISTS (SELECT 1 -- 这里可以书写适当的常数FROM shopproduct AS spWHERE sp.shop_id 000CAND sp.product_id p.product_id); -------------------------- | product_name | sale_price | -------------------------- | 运动T恤 | 4000 | | 菜刀 | 3000 | | 叉子 | 500 | | 擦菜板 | 880 | -------------------------- 4 rows in set (0.00 sec)大家可以把在 EXIST 的子查询中书写 SELECT * 当作 SQL 的一种习惯。 使用NOT EXIST替换NOT IN 就像 EXIST 可以用来替换 IN 一样 NOT IN 也可以用NOT EXIST来替换。 下面的代码示例取出不在大阪门店销售的商品的销售单价。 SELECT product_name, sale_priceFROM product AS pWHERE NOT EXISTS (SELECT *FROM shopproduct AS spWHERE sp.shop_id 000AAND sp.product_id p.product_id); -------------------------- | product_name | sale_price | -------------------------- | 菜刀 | 3000 | | 高压锅 | 6800 | | 叉子 | 500 | | 擦菜板 | 880 | | 圆珠笔 | 100 | -------------------------- 5 rows in set (0.00 sec)NOT EXIST 与 EXIST 相反当“不存在”满足子查询中指定条件的记录时返回真TRUE。 3.5 CASE 表达式 3.5.1 什么是 CASE 表达式 CASE 表达式是函数的一种。是 SQL 中数一数二的重要功能有必要好好学习一下。 CASE 表达式是在区分情况时使用的这种情况的区分在编程中通常称为条件分支。 CASE表达式的语法分为简单CASE表达式和搜索CASE表达式两种。由于搜索CASE表达式包含简单CASE表达式的全部功能。本课程将重点介绍搜索CASE表达式。 语法 CASE WHEN 求值表达式 THEN 表达式WHEN 求值表达式 THEN 表达式WHEN 求值表达式 THEN 表达式... ELSE 表达式 END上述语句执行时依次判断 when 表达式是否为真值是则执行 THEN 后的语句如果所有的 when 表达式均为假则执行 ELSE 后的语句。 无论多么庞大的 CASE 表达式最后也只会返回一个值。 3.5.2 CASE表达式的使用方法 假设现在 要实现如下结果 A 衣服 B 办公用品 C 厨房用具因为表中的记录并不包含“A ”或者“B ”这样的字符串所以需要在 SQL 中进行添加。并将“A ”“B ”“C ”与记录结合起来。 应用场景1根据不同分支得到不同列值 SELECT product_name,CASE WHEN product_type 衣服 THEN CONCAT(A ,product_type)WHEN product_type 办公用品 THEN CONCAT(B ,product_type)WHEN product_type 厨房用具 THEN CONCAT(C ,product_type)ELSE NULLEND AS abc_product_typeFROM product; -------------------------------- | product_name | abc_product_type | -------------------------------- | T恤 | A 衣服 | | 打孔器 | B 办公用品 | | 运动T恤 | A 衣服 | | 菜刀 | C 厨房用具 | | 高压锅 | C 厨房用具 | | 叉子 | C 厨房用具 | | 擦菜板 | C 厨房用具 | | 圆珠笔 | B 办公用品 | -------------------------------- 8 rows in set (0.00 sec)ELSE 子句也可以省略不写这时会被默认为 ELSE NULL。但为了防止有人漏读还是希望大家能够显示地写出 ELSE 子句。 此外 CASE 表达式最后的“END”是不能省略的请大家特别注意不要遗漏。忘记书写 END 会发生语法错误这也是初学时最容易犯的错误。 应用场景2实现列方向上的聚合 通常我们使用如下代码实现行的方向上不同种类的聚合这里是 sum SELECT product_type,SUM(sale_price) AS sum_priceFROM productGROUP BY product_type; ------------------------- | product_type | sum_price | ------------------------- | 衣服 | 5000 | | 办公用品 | 600 | | 厨房用具 | 11180 | ------------------------- 3 rows in set (0.00 sec)假如要在列的方向上展示不同种类额聚合值该如何写呢 sum_price_clothes | sum_price_kitchen | sum_price_office ------------------------------------------------------5000 | 11180 | 600聚合函数 CASE WHEN 表达式即可实现该效果 -- 对按照商品种类计算出的销售单价合计值进行行列转换 SELECT SUM(CASE WHEN product_type 衣服 THEN sale_price ELSE 0 END) AS sum_price_clothes,SUM(CASE WHEN product_type 厨房用具 THEN sale_price ELSE 0 END) AS sum_price_kitchen,SUM(CASE WHEN product_type 办公用品 THEN sale_price ELSE 0 END) AS sum_price_officeFROM product; -------------------------------------------------------- | sum_price_clothes | sum_price_kitchen | sum_price_office | -------------------------------------------------------- | 5000 | 11180 | 600 | -------------------------------------------------------- 1 row in set (0.00 sec)扩展内容应用场景3实现行转列 假设有如下图表的结构 计划得到如下的图表结构 聚合函数 CASE WHEN 表达式即可实现该转换 -- CASE WHEN 实现数字列 score 行转列 SELECT name,SUM(CASE WHEN subject 语文 THEN score ELSE null END) as chinese,SUM(CASE WHEN subject 数学 THEN score ELSE null END) as math,SUM(CASE WHEN subject 外语 THEN score ELSE null END) as englishFROM scoreGROUP BY name; ------------------------------ | name | chinese | math | english | ------------------------------ | 张三 | 93 | 88 | 91 | | 李四 | 87 | 90 | 77 | ------------------------------ 2 rows in set (0.00 sec)上述代码实现了数字列 score 的行转列也可以实现文本列 subject 的行转列 -- CASE WHEN 实现文本列 subject 行转列 SELECT name,MAX(CASE WHEN subject 语文 THEN subject ELSE null END) as chinese,MAX(CASE WHEN subject 数学 THEN subject ELSE null END) as math,MIN(CASE WHEN subject 外语 THEN subject ELSE null END) as englishFROM scoreGROUP BY name; ------------------------------ | name | chinese | math | english | ------------------------------ | 张三 | 语文 | 数学 | 外语 | | 李四 | 语文 | 数学 | 外语 | ------------------------------ 2 rows in set (0.00 sec总结 当待转换列为数字时可以使用SUM AVG MAX MIN等聚合函数当待转换列为文本时可以使用MAX MIN等聚合函数 练习题-第二部分 3.5 运算或者函数中含有 NULL 时结果全都会变为NULL 判断题 正确 3.6 对本章中使用的 product商品表执行如下 2 条 SELECT 语句能够得到什么样的结果呢 ① SELECT product_name, purchase_priceFROM productWHERE purchase_price NOT IN (500, 2800, 5000);**结果为 product_name | purchase_price | ** **| 打孔器 | 320 ** ** | 擦菜板 | 790 ** ** 不包含 purchase_price 为 NULL 的商品这是因为 谓词⽆法与 NULL 进⾏⽐较。 ** ② SELECT product_name, purchase_priceFROM productWHERE purchase_price NOT IN (500, 2800, 5000, NULL);**结果 返回了零条记录 这是因为 NOT IN 的参数中不能包含 NULL 否则查询结果通常为空。 ** 3.7 按照销售单价 sale_price对练习 6.1 中的 product商品表中的商品进行如下分类。 低档商品销售单价在1000日元以下T恤衫、办公用品、叉子、擦菜板、 圆珠笔中档商品销售单价在1001日元以上3000日元以下菜刀高档商品销售单价在3001日元以上运动T恤、高压锅 请编写出统计上述商品种类中所包含的商品数量的 SELECT 语句结果如下所示。 执行结果 low_price | mid_price | high_price ---------------------------------5 | 1 | 2SELECT SUM(CASE WHEN sale_price 1000 THEN 1 ELSE 0 END) AS low_price,SUM(CASE WHEN sale_price BETWEEN 1001 AND 3000 THEN 1 ELSE 0 END) AS mid_price,SUM(CASE WHEN sale_price 3001 THEN 1 ELSE 0 END) AS high_priceFROM product;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黄页88网站网络营销推广方式包括哪几种

1. ES6的解构ES6中引入了解构赋值的操作,其作用是:将值从数组Array或属性从对象Object提取到不同的变量中即分为两种情况:从数组Array中解构,以及从对象Object中解构①.从数组中解构const [a, b] [1, 2]//a 1, b 2当然这些是基…

社区智慧警务网站如何推进警务室建设方案网站推广手段有哪些

深度学习 | TCN时间卷积神经网络模型答疑 目录 深度学习 | TCN时间卷积神经网络模型答疑问题汇总问题回答参考资料问题汇总 1.使用 TCN 进行序列建模有哪些优势? 2.TCN 的特征? 问题回答 1.使用 TCN 进行序列建模具备以下优势: 并行性。与 RNN 中后继时间步长的预测必须等待…

如何跟客户沟通网站建设做网站还有搞头吗

GO 中的方法是什么? 前面我们有分享到 GO 语言的函数,他是一等公民,那么 GO 语言中的方法和函数有什么区别呢? GO 语言中的方法实际上和函数是类似的,只不过在函数的基础上多了一个参数,这个参数在 GO 语…

什么秀网站做效果图宝安中心站

上一篇文章讲到了 union,union union存在很多问题,因此C17设计了一个新的variant替代原来的union。 union的问题 无法知道当前使用的类型是什么。而且union无法自动调用底层数据成员的析构函数。 这些使得一般只对一些“基本类型”使用union&#xf…

已有网站如何做直播网站开发语言格式化标记语言

Python中没有提供计算两组变量非线性相关系数的包或接口。x和x^2的皮尔森相关系数可能接近于0,因为求的是线性相关性。但是这两个变量并不是独立不相关的。使用距离相关系数就可以计算x和x^2的非线性关系,如果距离相关系数接近于0,就可以说两…

商丘网站建设软件公司物流网站后台

最近这俩天正好有时间给自己做一下减法,忘记是去年还是今年,在升级 AndroidStudio 后使用 Logcat查看日志的方式也发生了一些变化,虽然一直在使用,但每当看到之前还未关闭 Logcat 命令行工具额昂也,就感觉可能还存在知…

阿里云虚拟主机可以做两个网站wordpress等待响应

前缀和 一.一维前缀和(模板):1.思路一:暴力解法2.思路二:前缀和思路 二. 二维前缀和(模板):1.思路一:构造前缀和数组 三.寻找数组的中心下标:1.思路一:前缀和 四.除自身以外数组的乘积&#xff…

网站开发和运维区别灰色词快速上排名

来源:量子位原标题:只需2小时,成本不到7块,你我皆可制作的3D机器人机器人的骨架能像昆虫那般灵活、健壮吗?这个问题一直困扰着研究人员。以往,要么制作工艺太过复杂,耗的时间长;要么…

上虞做网站公司数据库查询网站模板

腾讯MMKV使用 implementation com.tencent:mmkv-static:1.2.9 MMKV.initialize(this);//会返回MMVK存储的目录(String) 创建MMKV,可以通过 defaultMMKV() 来创建,这个是全局默认的;也可以通过 mmkvWithID() 对应自己业…

3g免费网站制作php餐饮美食店网站源码 生成html

计算机辅助教学应用现状及对策研究 (8页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!9.9 积分计算机辅助教学应用现状及对策研究摘要:新形势下,计算机辅助教学迅速发展&…

蓬莱做网站案例怎么批量修改wordpress文章内容

题目题目描述写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下: F(0) 0, F(1) 1F(N) F(N - 1) F(N - 2), 其中 N > 1. 斐波那契数列由 0 和 1 开始,之后的斐波那契数…

网站和服务器是什么ppt链接网站怎么做

1. 题目 给你两个单词 s 和 t,请你计算出将 s 转换成 t 所使用的最少操作数。 你可以对一个单词进行如下两种操作: 删除一个字符替换一个字符 注意: 不允许插入操作 题目保证有解 示例: 输入:s "abcdefg&qu…

国有资产处网站建设进贤城乡规划建设局网站

一、简介 Spring Cloud Function 是基于 Spring Boot的函数计算框架。该项目致力于促进函数为主的开发单元,它抽象出所有传输细节和基础架构,并提供一个通用的模型,用于在各种平台上部署基于函数的软件。在Spring Cloud Function相关版本&am…

网站建设及制作教程做一个企业网站多少钱

文章目录 1.几种常用的事务传播行为1.1 REQUIRED1.2 REQUIRES_NEW1.2 NESTED 2. 事务问题2.1 事务不生效?2.2 事务不回滚? 文章会分为两个部分来讲解,第一部分是声明式事务的几种使用场景。第二部分包含事务没有生效,没有回滚的情…

怎么自己创建一个网站手机网站建设整体设计思路

本文作者祈澈姑娘,转载请声明 前端的技术日渐更新,最近得空,花了一上午的时间,将前端常见的框架总结了一下,在开发的过程之中,有了这些,不断能够提高自己的工作效率,还可以在工作之余…

it网站设计网站的增加条件设计

485转换器主要的作用是将单端的RS-232信号转换为平衡差分的RS-485或RS-422信号。RS-485、RS-422自动识别功能,使用更加简单。接下来就由飞畅科技的小编来为大家详细介绍下485转换器的产品功能特点及技术参数,一起来看看吧! 485转换器产品特点…

云邦北京网站建设销售网站建设推广

给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 示例 1: 输入:nums [1,2,3], target 4 输出:7 解释&#…

和别人做网站接单赚钱中小型网站建设多少钱

一、题目介绍 输入描述: 多组输入,每行输入一个正整数(不大于100)。 输出描述: 针对每行输入的整数n,输出两行,第一行,输出n之内(包括n)的素数&#xff0…

外贸网站建设工作室百度会收录双域名的网站么

Windows 故障转移Hyper-V 虚机自动迁移高 可用 Windows 故障转移Hyper-V 虚机自动迁移高... 1一、系统原理... 31.1 高效率的 VMbus 架构... 31.2 完美支持 Linux 系统... 4二、架构拓朴... 52.1 网络及系统架构拓朴... 52.2 域结构拓朴... 5三、实验资源列表... 63.1 网络设备…

永春县住房和城乡规划建设局网站上海知名的seo推广咨询

Mathtype公式自动转Word自带公式 前言/word技巧探索过程参考资料(有效与无效)全自动方案/代码/教程 前言/word技巧 word公式 用ALT号可以输入简单latex显示公式;复杂度,需要引入latex包的不行;显示不出来的话按一下en…