Loading... ## 前言 这篇文章主要是介绍数据库的基础查询相关操作,适合没有任何数据库操作基础的人员查阅。如果您有相关的数据库开发经验,那这篇文章将对您没有任何帮助。 ## 表连接分类 联接查询分为**内联接、**外联接**、**交叉联接**。** ### 内连接 <div class="tip inlineBlock success simple small"> 1️⃣ 最典型、最常用的连接查询 2️⃣ 根据两张表中共同的列进行匹配 3️⃣ 两个表存在主外键关系时,通常会使用内连接查询 </div> 演示案例表结构分析: **图书信息表 [BookInfo]** | Id | Name | Price | Author | CId | | -- | ------------------- | ----- | ---------------- | --- | | 1 | C#高级 | 156 | 克里斯琴•内格尔 | 1 | | 2 | SQL Server高级编程 | 128 | 美维埃拉 | 1 | | 3 | WinForm程序设计 | 58 | 王希斌 | 1 | | 4 | 美术概论 | 20 | 艾苓 | 2 | **图书分类表 [BookCategory]** | CId | CategoryName | | --- | ------------ | | 1 | IT类 | | 2 | 艺术类 | | 3 | 科普类 | 内连接语法: ```sql SELECT 列名 FROM 表名1 INNER JOIN 表名2 ON 表名1.列 = 表名2.列 --INNER可以省略,ON用来设置两个表之间的关联条件 ... WHERE 筛选条件 /* INNER JOIN 关键字后面是关联表,ON关键字后是表间联接字段的关系 */ ``` 演示案例: ```sql SELECT B.Id, C.CategoryName, B.Name, B.Price, B.Author FROM BookInfo B INNER JOIN BookCategory C ON B.CId = C.CId -- 使用WHERE子句实现内连接[不推荐],下面代码执行后可以得到相同的执行结果 SELECT B.Id, C.CategoryName, B.Name, B.Price, B.Author FROM BookInfo B,BookCategory C WHERE B.CId = C.CId ``` 执行结果: | Id | Name | Price | Author | CategoryName | | -- | ------------------- | ----- | ---------------- | ------------ | | 1 | C#高级 | 156 | 克里斯琴•内格尔 | IT类 | | 2 | SQL Server高级编程 | 128 | 美维埃拉 | IT类 | | 3 | WinForm程序设计 | 58 | 王希斌 | IT类 | | 4 | 美术概论 | 20 | 艾苓 | 艺术类 | ### 外连接 <div class="tip inlineBlock success simple small"> **特点:** 1️⃣ 外连接可以分为主表和从表 2️⃣ 主表的数据会被完全显示出来 3️⃣ 从表中只显示满足连接条件的数据 4️⃣ 外连接结果一般会比主表和从表中数据量最小的表中的数据多 **分类:** 左外连接(LEFT JOIN) 右外连接(RIGHT JOIN) 完全连接(FULL JOIN) </div> 演示案例表结构分析: **用户信息表 [UserInfo]** | UserId | UserName | | ------ | -------- | | 1 | 张三 | | 2 | 李四 | | 3 | 夏颖 | | 4 | 李沁 | **图书借阅记录表 [BorrowInfo]** | BId | UserId | BorrowDate | | --- | ------ | ---------- | | 1 | 1 | 2021-02-03 | | 2 | 1 | 2021-02-03 | | 3 | 2 | 2021-02-05 | | 4 | 3 | 2021-03-05 | **内连接语法:** ```sql SELECT 列名 FROM 表名1 LEFT [OUTER] JOIN 表名2 ON 表名1.列 = 表名2.列 --OUTER可以省略,ON用来设置两个表之间的关联条件,LEFT可以替换为:RIGHT \ FULL ... WHERE 筛选条件 ``` 演示案例: ```sql -- 统计每位用户的借书情况并显示没有借阅过图书的用户 SELECT U.UserName,B.BorrowDate,B.BId FROM UserInfo U LEFT OUTER JOIN BorrowInfo B ON B.UserId = U.UserId ``` 查询结果: | UserName | BId | BorrowDate | | -------- | ---- | ---------- | | 张三 | 1 | 2021-02-03 | | 张三 | 2 | 2021-02-03 | | 李四 | 3 | 2021-02-05 | | 夏颖 | 4 | 2021-03-05 | | 李沁 | NULL | NULL | <div class="tip inlineBlock info simple small"> 主表(左表)UserInfo中的数据逐条匹配表BorrowInfo中的数据 • 匹配,返回到结果集 • 无匹配,NULL值返回到结果集 💬 左外联接是以左表为基础的,左表的记录将会全部表示出来,而右表只会显示符合搜索条件的记录。右表记录不足的地方均为NULL **右外连接:** 右外连接的原理与左外连接相同 右表逐条匹配记录,否则使用NULL填充 **完全连接:** 会从两个连接表中获取数据 如果有对应关系,则会填上对应数据;否则,以NULL值填充 </div> ## 聚合函数 **概念:**对一组值进行计算,并返回计算后的值,具有统计数据的作用 | 函数名称 | 说明 | 注意 | | ---------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SUM() | 返回表达式中所有值的和 | • 用于返回表达式中所有值的和<br />• 只能用于数字列<br />• 如果参与计算记录在该列上的值为空值(`NULL`),则此条记录在计算中将被忽略 | | AVG() | 返回表达式的平均值 | • 用于返回表达式中所有数值的平均值<br />• 该列值为空(`NULL`)的记录将被忽略 | | MIN() | 返回表达式的最小值 | • 返回表达式中的最小值<br />• 如果出现空值(`NULL`),则该记录将被忽略<br />• 用于数值、字符串和日期类型的数据列 | | MAX() | 返回表达式的最大值 | • 返回表达式中的最大值,和MIN()注意点一致 | | COUNT() | 返回查询记录的总个数 | • 返回提供的组或记录集中的计数<br />• 用于除 `text`、`image`、`ntext`以外任何类型的列<br />• 使用星号(*)作为COUNT函数的参数 [***不推荐,推荐使用数字0或者列名**]<br />• 可以不必指定特定的列而计算所有的行数<br />• 当对所有的行进行计数时,包括包含空值(`NULL`)的行 | | DISTINCT() | 返回一个集合,并从指定的集合中删除重复项 | / | <div class="tip inlineBlock error simple small"> ⚠ 注意:在使用聚合函数查询后,查询列表中将不能出现普通列,除非该列也是用了聚合函数或使用了分组(GROUP BY) </div> 演示案例: ```sql -- 查询出学员编号为'S230100801'的考试总成绩,平均分,最高分以及最低分 SELECT SUM(Result) '总成绩', AVG(Result) '平均分', MAX(Result) '最高分', MIN(Result) '最低分', FROM ResultInfo WHERE StudentNo = 'S230100801' -- 查询出学员编号为'S230100801'的考试成绩大于90分的次数 SELECT COUNT(0) '大于90分的考试次数' FROM Result WHERE StudentNo = 'S230100801' AND Result >= 90 ``` ## 分组查询 **语法:** ```sql SELECT 分组列名1,分组列名2,聚合函数(列名)... FROM 表名 WHERE 原始表数据筛选条件 GROUP BY 分组列名1,分组列名2... HAVING 分组后的数据筛选条件 ORDER BY 排序列名 ``` <div class="tip inlineBlock error simple small"> ⚠ 注意:在使用分组查询后,查询列表中将不能出现普通列,除非该列使用了分组(GROUP BY)或者使用了聚合函数 </div> 演示案例: ```sql -- 查询出每门科目的考试平均分 SELECT SubjectID,AVG(Result) FROM ResultInfo GROUP BY SubjectID -- 查询出每门科目的考试最高分,按降序排列 SELECT SubjectID,MAX(Result) FROM ResultInfo GROUP BY SubjectID ORDER BY MAX(Result) DESC -- 查询出每个学员,每个科目的考试总成绩,按学员编号排列 SELECT StudentNo,SubjectID,SUM(Result) FROM ResultInfo GROUP BY StudentNo,SubjectID ORDER BY StudentNo -- 查询出每门科目考试成绩大于80分的总人数 SELECT SubjectID,COUNT(0) FROM ResultInfo WHERE Result >= 80 GROUP BY SubjectID -- 查询出每门科目的考试平均分且平均分高于80分并按降序排列 SELECT SubjectID,AVG(Result) FROM ResultInfo GROUP BY SubjectID HAVING AVG(Result) >= 80 ORDER BY AVG(Result) DESC ``` ### WHERE与HAVING对比 `WHERE `是对分组之前的原始表记录中的数据进行筛选 `HAVING `是对分组之后的分组数据进行筛选,`HAVING`只能配合`GROUP BY`使用,不能单独使用 `ORDER BY` 子句只允许出现在查询语句的最末尾 最后修改:2023 年 10 月 09 日 © 允许规范转载 赞 2 都滑到这里了,不点赞再走!?