从零开始学SQL数据分析,SQL子函数
子查询用于为主查询返回其所需数据,或者对检索数据进行进一步的限制,通常将一个查询(子查询)的结果作为另一个查询(主查询)的数据来源或判断条件,常见的子查询有WHERE子查询,HAVING子查询,FROM子查询,SELECT子查询,EXISTS子查询。
子查询是一种嵌套在其他SQL查询的WHERE子句中的查询,可以在SELECT、INSERT、UPDATE和DELETE语句中,同逻辑运算符一起使用。示例工具:MySQL8。0、NavicatPremium12
本文讲解内容:SQL子查询
适用范围:子查询在SQL数据分析中的应用
使用子查询必须遵循以下几个规则:子查询必须括在圆括号中。子查询的SELECT子句中只能有一个列,除非主查询中有多个列,用于与子查询选中的列相比较。子查询不能使用ORDERBY,不过主查询可以。在子查询中,GROUPBY可以起到同ORDERBY相同的作用。返回多行数据的子查询只能同多值操作符一起使用,比如IN操作符。SELECT列表中不能包含任何对BLOB、ARRAY、CLOB或者NCLOB类型值的引用。子查询不能直接用在聚合函数中。BETWEEN操作符不能同子查询一起使用,但是BETWEEN操作符可以用在子查询中。
创建数据表
通常情况下子查询都与SELECT语句一起使用,其基本语法如下所示:SELECTcolumnname〔,columnname〕FROMtable1〔,table2〕WHEREcolumnnameOPERATOR(SELECTcolumnname〔,columnname〕FROMtable1〔,table2〕〔WHERE〕)
对于子查询的数据演示创建两个表,一个是薪水表,另一个是职位表,并且插入数据。创建薪水表SALARYCREATETABLESALARY(IDVARCHAR(10),NAMEVARCHAR(10),AGEVARCHAR(10),ADDRESSVARCHAR(10),SALINT(10));
给薪水表插入数据,数据内容如下所示:给薪水表插入数据INSERTINTOSALARY(ID,NAME,AGE,ADDRESS,SAL)VALUES(C001,Rmesh,35,Ahmedabad,2000),(C002,Khilan,25,Delhi,1500),(C003,Kaushik,23,Kota,2000),(C004,Chaitali,25,Mumbai,6500),(C005,Hardik,27,Bhopal,8500),(C006,Komal,22,MP,4500),(C007,Tom,26,MP,5500),(C008,Muffy,24,Indore,10000);
查询所有的薪水数据如下所示:SELECTFROMSALARY;
同理创建一个职位表。创建职位表JOBCREATETABLEJOB(JIDVARCHAR(10),JBVARCHAR(10));
给职位表插入数据,数据内容如下所示:给职位表插入数据INSERTINTOJOB(JID,JB)VALUES(C001,Teacher),(C002,Docter),(C003,Teacher),(C004,Worker),(C005,Nurse),(C006,Teacher),(C007,Docter),(C008,Teacher);
查询所有的职位数据如下所示:SELECTFROMJOB;
子查询过滤
子查询最常见的使用是在WHERE子句的IN操作符中,以及用来填充计算列。先看一个简单的例子,要查询所有医生的薪水情况,这里首先在职位表中查询所有医生的JID,查询结果如下:SELECTJIDFROMJOBWHEREJBDocter;
然后在薪水表中查询ID为C002,C007的薪水情况,查询结果如下:SELECTSALFROMSALARYWHEREIDIN(C002,C007);
这里使用子查询更加简便,子查询从内向外依次处理,在下面的SELECT语句中,MySQL实际上执行了两个操作,首先查询返回两个ID号:C002和C007。
然后,这两个值以IN操作符要求的逗号分隔的格式传递给外部查询的WHERE子句,可以看到输出的结果是正确的,并且与前面WHERE子句所返回的值相同。SELECTSALFROMSALARYWHEREIDIN(SELECTJIDFROMJOBWHEREJBDocter);
使用子查询查询薪水大于8000的员工的所有信息,首先内部查询薪水大于8000的ID,然后外部使用一个WHERE查询即可得到结果。SELECTFROMSALARYWHEREIDIN(SELECTIDFROMSALARYWHERESAL8000);
作为计算字段使用子查询
使用子查询的另一方法是创建计算字段,创建计算字段需要使用聚合函数,例如count,sum,avg,max,min等,这里首先计算平均薪水作为一个内查询,然后在外部使用WHERE子句进行查询,得出薪资比平均薪资低的员工的所有信息。SELECTFROMSALARYWHERESAL(SELECTAVG(SAL)FROMSALARY);
除使用WHERE过滤,还可以使用HAVING过滤,HAVING子句对分组统计函数进行过滤,也可以在HAVING子句中使用子查询,要查询薪资最高的人及其薪资情况,首先内部查询最高工资,然后外部以人名分组后使用HAVING子句过滤,查询结果如下。SELECTNAME,SALFROMSALARYGROUPBYNAMEHAVINGSAL(SELECTMAX(SAL)FROMSALARY);