一、高级查询
1. 计算函数
AVG
AVG()为平均值函数,通过对表中行数计数并计算其列值之和 ,求得该列的平均值。 AVG() 可用来返回所有列的平均值,也可以用来返回特定列或行的平均值。
sql
Select avg(gpa)
From user_profile
COUNT
COUNT()函数为计数函数,可利用 COUNT() 确定表中行的数目或符合特定条件的行的数目。
COUNT()函数有两种使用方式:
- 使用 COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
- 使用 COUNT(column)对特定列中具有值的行进行计数,忽略 NULL 值。
MAX
MAX()返回指定列中的最大值。MAX在使用时,()需指定要返回最大值的列名称
MIN
MIN()的功能正好与 MAX()功能相反,它返回指定列的最小值。与 MAX() 一样,MIN()要求指定列名
SUM
SUM()用来返回指定列值的和(总计)。
取整函数
在一些聚集运算中,容易出现结果为非整数的情况,这时候如果想要限定结果返回的小数位数就可以使用SQL中内置的round函数 ,语法格式为round(value,n),其中value代表想要限制小数位数的字段,n代表想要限制的小数位数。
下列语句就代表求age列的均值,并保留一位小数。
sql
SELECT round(avg(age),1) AS avg_age FROM user_profile
2. 分组查询
分组查询数据,涉及到两个新 SELECT 语句子句:GROUP BY 子句和 HAVING 子句。
分组计算
在使用Group by时,有一些事项需要注意:
-
GROUP BY 子句可以包含任意数目的列,因而可以对分组进行嵌套, 更细致地进行数据分组。
-
除聚集计算语句外,SELECT 语句中的每一列都必须在 GROUP BY 子句中同时给出。
-
如果分组列中包含具有 NULL 值 的行,则NULL 将作为一个分组返回。 如果列中有多行 NULL 值,它们将分为一组。
-
GROUP BY 子句必须出现在 WHERE 子句之后,ORDER BY 子句之前。
举个🌰:
sqlSELECT university,avg(gpa) AS avg_gpa FROM user_profile Group By university
GROUP BY 子句指示SQL按university分组分别计算每个学校的平均gpa情况,结果返回每个大学的平均gpa数值。
分组过滤
除了能用 GROUP BY 分组数据外,SQL 还允许在分组的结果下进行过滤,分组查询的结果不能简单的使用Where语句进行过滤,而需要使用专门的Having语句。
在上一章节题目中,我们计算了不同性别和不同学校分组下的用户30天内平均活跃天数情况,假如说我们只想要取出平均活跃天数在10天以上的分组,这时就可以用到Having语句,来看示范 :
举个🌰:
sqlSELECT gender,university,count(device_id) as user_num, avg(active_days_within_30) as avg_active_days, avg(question_cnt) as avg_question_cnt FROM user_profile Group By gender,universityHaving avg(active_days_within_30) >10
在最后一行中增加 HAVING 子句,并搭配使用了avg(active_days_within_30) >10的条件,最终结果中就只会返回30天平均活跃天数大于10的分组。
二、多表查询
1. 子查询
SQL 允许创建子查询(subquery),即嵌套在其他查询中的查询。
举个🌰:
sqlSELECT device_id, question_id, result FROM question_practice_detail WHERE device_id IN (SELECT device_id FROM user_profile WHERE university ='山东大学');
在 SELECT 语句中,子查询总是从内向外处理。在处理上面的 SELECT 语 句时,DBMS实际上执行了两个操作。
首先,它执行下面的查询:
sqlSELECT device_id FROM user_active WHERE university ='山东大学'
这个查询可以返回所有的山东大学用户的device_id, 然后,这些值**以IN 操作符要求的逗号分隔的格式传递给外部查询的 WHERE 子句,**外部查询变成:
sqlSELECT cust_id FROM orders WHERE order_num IN (5432,,2131) ,
数据库管理系统(Data Base Management System,DBMS)是管理和维护数据库的系统软件。
2. 连接查询
理解关系表的概念
SQL 最强大的功能之一就是能在数据查询的执行中联结(join)表 。关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。 下面我们来介绍一些常见的链接方式:
Join链接方式
1. 左链接
左连接的定义:是以左表为基础,根据ON后给出的两表的条件将两表连接起来。 结果会将左表所有的查询信息列出,而右表只列出ON后条件与左表满足的部分 。左连接全称为左外连接,是外连接的一种。其语句为Left join .. on
在使用Left Join时有几个注意要点:
- 在使用Left join 时,写在前面的表为匹配时的底表,使用on给出匹配条件,匹配条件可以不唯一。
- 在表匹配时,一般我们会将要匹配的两段查询用括号括起来,并在括号末尾给予一串字母,作为表的别名。
- 在使用on写匹配条件时,如果两个表中有字段名称一样 ,需要用表名.字段的写法指出该字段取自哪一个表,在最终Select语句输出时同理,可以看到设备ID最终输出的写法是a.device_id,因为device_id同时存在于两个表中,我们这里指定要用a表中 的device_id列来输出。
举个🌰:
sqlSelect a.device_id,question_id,result,level,gender,age from ( Select device_id,question_id,result,level From question_practice_detail )a -- 表别名 Left join ( Select device_id,gender,age From user_profile )b -- 表别名 On a.device_id = b.device_id ---给出链接条件
2. 右链接
右向外联接是左向外联接的反向联接,是**以右表为基础,返回右表的所有行,**和左链接没有本质上的区别。
3. 内链接
内连接是A表的所有行和B表的所有行在指定条件下得到的交集 ,所用到的语句为Join
笛卡尔积
在写表与表之间的链接关系时,大多数情况下都必须要限制匹配条件,如果在匹配时没用限制匹配条件,这时就会导致笛卡尔积。
笛卡尔积是关系代数里的一个概念,表示两个表中的每一行数据任意组合,即假设表A中有n行数据,表b中有m行数据,没有限制匹配条件的话,最终输出的结果就会有m*n行数据 ,在互联网大体量数据情况下,每个表可能有几百万几千万行数据,几千万*几千万最终得到的结果行数会是天文数字,所以在写匹配时,一定不要忘了加上匹配条件。
3. 组合查询
多数 SQL 查询只包含从一个或多个表中返回数据的单条 SELECT 语句。 但是,SQL 也 允许执行多个查询(多条 SELECT 语句),并将结果作为一 个查询结果集返回。这些组合查询通常称为并(union)或复合查询 (compound query)。
主要有两种情况需要使用组合查询:
- 在一个查询中从不同的表返回结构数据;
- 对一个表执行多个查询,按一个查询返回数据。
union
可用 UNION 操作符来组合数条 SQL 查询。利用 UNION,可给出多条 SELECT 语句,将它们的结果组合成一个结果集。
使用 UNION 很简单,所要做的只是给出每条 SELECT 语句,在各条语句之间放上关键字UNION。但需要注意的是UNION 中的每个查询必须包含相同的列、表达式或聚集函数(不过, 各个列不需要以相同的次序列出)
union all
UNION 从查询结果集中自动去除了重复的行 ;换句话说,它的行为与一 条 SELECT 语句中使用多个 WHERE 子句条件一样,使用 UNION 时,重复的行会被自动取消。 这是UNION 的默认行为,如果想不去重的返回所有的匹配行,可使用 UNION ALL而不是UNION。