【牛客SQL快速入门】SQL基础(二)

一、高级查询

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时,有一些事项需要注意:

  1. GROUP BY 子句可以包含任意数目的列,因而可以对分组进行嵌套, 更细致地进行数据分组。

  2. 除聚集计算语句外,SELECT 语句中的每一列都必须在 GROUP BY 子句中同时给出。

  3. 如果分组列中包含具有 NULL 值 的行,则NULL 将作为一个分组返回。 如果列中有多行 NULL 值,它们将分为一组。

  4. GROUP BY 子句必须出现在 WHERE 子句之后,ORDER BY 子句之前。

举个🌰:

sql 复制代码
SELECT 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语句,来看示范 :

举个🌰:

sql 复制代码
SELECT 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),即嵌套在其他查询中的查询。

举个🌰:

sql 复制代码
SELECT
device_id,
question_id,
result
FROM question_practice_detail
WHERE device_id IN (SELECT device_id FROM user_profile
WHERE university ='山东大学');

在 SELECT 语句中,子查询总是从内向外处理。在处理上面的 SELECT 语 句时,DBMS实际上执行了两个操作。

首先,它执行下面的查询:

sql 复制代码
SELECT device_id FROM user_active WHERE university ='山东大学'

这个查询可以返回所有的山东大学用户的device_id, 然后,这些值**以IN 操作符要求的逗号分隔的格式传递给外部查询的 WHERE 子句,**外部查询变成:

sql 复制代码
SELECT 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列来输出。

举个🌰:

sql 复制代码
Select 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。

相关推荐
woshilys13 分钟前
sql server 查询对象的修改时间
运维·数据库·sqlserver
Hacker_LaoYi14 分钟前
SQL注入的那些面试题总结
数据库·sql
建投数据1 小时前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云
Hacker_LaoYi2 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀2 小时前
Redis梳理
数据库·redis·缓存
独行soc2 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天3 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺3 小时前
分布式系统架构:服务容错
数据库·架构
独行soc4 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain4 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu