查询排序与表连接

news/2025/10/29 22:45:33/文章来源:https://www.cnblogs.com/honey111/p/19172916

一、分组(group by)相关
(一)分组(group by)的作用
按逻辑次序合并具有重复值的字段,用于查看指定分组的聚合情况,查询结果可同时包含普通列和聚合函数(如 avg、max、min、count 等)。
(二)分组与过滤的语法逻辑
where 子句:用于分组前过滤数据,缩小数据范围,语法为where 过滤条件。
group by 子句:指定分组的列,支持多个列组合分组,语法为group by column1, column2。
having 子句:用于分组后过滤数据,仅作用于分组后的结果,需结合聚合函数使用,语法为group by 分组列 having 聚合函数条件。
(三)分组列与 select 子句的关系
出现在select子句中的单独普通列(非聚合函数对应的列),必须出现在group by子句中作为分组列,列的顺序可不同。
(四)分组相关示例
(分组/占队) group by 列名,按哪列分组就显示此列名,分组的列通常和聚合一起使用
1.按科目分组,统计每个科目的平均分、最高分、最低分
select student_subject ,avg(score)'平均表',max(score)'最高分',min(score)'最低分'
from student_score
group by student_subject;

2.按科目分组,统计每个科目的考试人数
select student_subject'科目', count(*)'人数'
from student_score
group by student_subject;

3.按科目分组,统计2025 年 9 月 1 日考试的每个科目的平均分和考试人数
select student_subject'科目' ,avg(score)'平均分',count(*)'考试人数'
from student_score
where edate='2025-09-01'
group by student_subject;

4.按科目分组,筛选出 “平均分数大于 80” 的科目,并显示该科目的平均分和考试人数
select student_subject'科目',avg(score)'平均分',count(*)'考试人数'
from student_score
group by student_subject
having avg(score)>80;
-- 分组前的条件是where select * from 表名 where ... group by 列名
-- 分组后的条件是having select * from 表名 group by 列名 having 聚合条件

5.对及格成绩,按科目分组,显示平均分达到80分的科目名的和科目平均分
select student_subject'科目',round(avg(score),1)'平均分'
from student_score
where score>60
group by student_subject
having avg(score)>80;

6.按城市分组,统计每个城市的记录数量(基于 employee_tbl 表)
select city, count(*)
from sales.employee_tbl
group by city;

7.按 emp_id 和 salary 分组,返回不同薪水的总和(基于 employee_pay_tbl 表)
select emp_id, sum(salary)
from sales.employee_pay_tbl
group by emp_id, salary;

8.group by 子句用整数代表字段名称(按雇佣年份分组,统计薪水总和)
select year(date_hire) as year_hired, sum(salary)
from sales.employee_pay_tbl
group by 1;

9.having 子句示例:查询除 greenwood 之外所有城市的平均小时工资和薪水,仅显示平均薪水超过 30000 的分组,并按平均薪水排序
select city, avg(pay_rate), avg(salary)
from sales.emp_pay_tmp
where city <> 'greenwood'
group by city
having avg(salary) > 30000
order by 3;

二、排序(order by)相关
(一)排序语法
order by 字段名 / 位置索引(如2、3) / 字段别名 [asc(升序,默认)/ desc(降序)]
(二)空值(null)处理
可通过order by 字段 is null控制空值位置,字段 is null判断结果中,null 值对应 true(相当于 1),非 null 值对应 false(相当于 0),排序时 0 在前、1 在后,即非 null 值在前、null 值在后。若需调整,可结合排序方向或函数(如 oracle 的 null first/nulls last)。
(三)排序示例
1.按平均分排序,空值放后面
select *
from 表名
order by avg(平均分) is null, 2;

2.按城市分组后,先按平均小时工资(位置索引 2)、再按平均薪水(位置索引 3)排序
select city, avg(pay_rate), avg(salary)
from sales.emp_pay_tmp
where city in ('whiteland', 'indianapolis')
group by city
order by 2, 3;
调整空值位置,让 null 值在平均薪水排序中放后面
select city, avg(pay_rate), avg(salary)
from sales.emp_pay_tmp
where city in ('whiteland', 'indianapolis')
group by city
order by avg(pay_rate) is null, 3;

三、表连接相关
(一)表连接类型及定义
内连接(inner join):最常用关联方式,也叫等值关联,通过通用字段关联两个表,仅返回两个表中至少有一个匹配的行。
左外连接(left [outer] join):以左表为主表,返回左表所有行,即使右表中无匹配,右表对应字段置为 null。
右外连接(right [outer] join):以右表为主表,返回右表所有行,即使左表中无匹配,左表对应字段置为 null。
全外连接(full [outer] join):只要其中一个表中存在匹配,就返回行;无匹配时,对应表字段置为 null(mysql 不支持,可通过 left join + union all + right join 实现)。
交叉连接(cross join,笛卡尔积):从左表循环取每条记录,与右表所有记录无条件匹配,无关联字段,结果行数为两表行数乘积。
自关联:利用表别名将表重命名,像处理两个不同表一样将表与自身关联,用于查询表内具有层级或关联关系的数据(如员工与主管)。
桥表连接:当两个表无公用字段时,通过第三个与两表均有公用字段的 “桥表” 关联,实现数据查询。

(二)各类表连接语法
1.内连接
标准语法(join...on 形式):
select table1.column1, table2.column2...
from table1
inner join table2 on table1.column_name = table2.column_name
[inner join table3 on table1.column_name = table3.column_name];
非标准语法(where 形式):
select table1.column1, table2.column2...
from table1, table2[, table3] [...]
where table1.column_name = table2.column_name
[and table1.column_name = table3.column_name];
关键区别:on 是 join 前的连接条件,定义表间关联规则,效率更高;where 是 join 后的筛选条件,对最终结果集过滤。

【示例】
(关联 employee_tbl 和 employee_pay_tbl 表,获取员工 id、姓氏、职位)
标准语法:
select employee_tbl.emp_id, employee_tbl.last_name, employee_pay_tbl.position
from sales.employee_tbl
inner join sales.employee_pay_tbl
on employee_tbl.emp_id = employee_pay_tbl.emp_id;
非标准语法:
select employee_tbl.emp_id, employee_tbl.last_name, employee_pay_tbl.position
from sales.employee_tbl, sales.employee_pay_tbl
where employee_tbl.emp_id = employee_pay_tbl.emp_id;
表的别名
select e.emp_id, e.last_name, ep.position
from sales.employee_tbl e
inner join sales.employee_pay_tbl ep
on e.emp_id = ep.emp_id;

2.外关联
外关联会返回一个表里的全部记录,即使对应的记录在第二个表里不存在。以某张表为主表,取出里面的所有记录,然后每条与另外一张表(副表)进行连接。不管能不能匹配上条件,主表中的数据都会保留;副表中的数据如果匹配上则保留,匹配不上则字段置NULL。外部关联被划分为左外关联、右外关联和全外联关联

from table1 {left | right | full} [outer] join table2 on .......{left | right | full} [outer] join table3 on .....
oracle :
可以写成from table1, table2 [, table3]where table1.column_name [(+)] = table2.column_name [(+)][and table1.column_name [(+)] = table3.column_name [(+)]]
【示例】
select p.prod_desc, o.qty
from sales.products_tbl p
left outer join sales.orders_tbl o on p.prod_id = o.prod_id

3.自关联
select t1.column_name, t2.column_name[, t3.column_name]
from table1 as t1
[inner join | left join | right join | full join] table1 as t2
on t1.column_name = t2.column_name
[ [inner join | left join | right join | full join ] table1 as t3
on t1.column_name = t3.column_name ];
【示例】
(查询员工及其主管信息,无主管则主管信息为 null)
select t1.employee_id, t1.last_name, t2.employee_id as manager_id, t2.last_name as manager_name
from hr.employees as t1
left outer join hr.employees as t2
on t1.manager_id = t2.employee_id

4.桥表连接
select 字段 from 桥表 as 桥表别名
inner join 表1 as 表1别名 on 桥表别名.关联字段1 = 表1别名.关联字段1
inner join 表2 as 表2别名 on 桥表别名.关联字段2 = 表2别名.关联字段2;
【示例】(通过 orders_tbl 桥表,关联 customer_tbl 和 products_tbl,获取客户名称与产品描述)

select c.cust_name, p.prod_desc
from sales.orders_tbl as o
inner join sales.customer_tbl as c on o.cust_id = c.cust_id
inner join sales.products_tbl as p on o.prod_id = p.prod_id;

5.交叉连接
select 字段 from 左表 cross join 右表;
等价于select 字段 from 左表, 右表;

6.全外连接示例(mysql 实现,关联 customers 和 orders 表)
select id, name, amount, ord_date from customers full join orders on customers.id = orders.customer_id;

Oracle中
select id, name, amount, ord_date
from sales.customers
left join sales.orders
on customers.id = orders.customer_id
union all
select id, name, amount, ord_date
from sales.customers
right join sales.orders
on customers.id = orders.customer_id;

四、sql 查询案例(含子查询)
1.查询每件产品的名称和价格,并找出最贵产品

方式 1(按价格降序排序,取第一条即为最贵产品):
select prod_desc, cost
from product_tbl
order by cost desc
limit 1;
方式 2(子查询,先查最高价格,再匹配产品):
select prod_desc, cost
from product_tbl
where cost = (select max(cost) from product_tbl);
2.从表employee_pay_rate里列出城市平均薪水高于33000的每个城市的平均薪水

select city, avg(salary) as 城市平均薪水
from employee_pay_rate
group by city
having avg(salary) > 33000;

3.编写一个 SQL 语句,从表 employee_tbl 返回 emp_id、last_name 和 first_name 字段,从表 employee_pay_tbl 返回 salary 和 bonus 字段。完成上述查询以后,再进一步计算出每个城市雇员的平均薪水是多少。

关联两张表查询员工基本信息与薪酬信息
select e.emp_id, e.last_name, e.first_name, p.salary, p.bonus
from employee_tbl e
inner join employee_pay_tbl p
on e.emp_id = p.emp_id;
按城市分组统计平均薪水
select e.city, avg(p.salary)
from employee_tbl e
inner join employee_pay_tbl p
on e.emp_id = p.emp_id
group by e.city;

4.使用products_tbl表,如下图:cost(价格)、产品 ID(prod_id)和产品描述(prod_desc)。
使用子查询编写一个SQL语句,列出所有价格高于全部产品平均价格的产品。
select prod_id, prod_desc
from products_tbl
where cost > (select avg(cost) from products_tbl);

解析:子查询(select avg(cost) from products_tbl)先计算所有产品的平均价格,外层查询筛选出价格高于该平均价格的产品,返回产品 id 和产品描述。

五、三大范式
主键:唯一且非空
函数依赖:完全依赖,部分依赖,传递依赖
范式升级的作用:解决关系模式的数据冗余、插入删除更新异常
(一)第一范式
关系中的每个属性都是不可再分的原子项(属性值不能是复合的,多值的)。可能存在完全依赖、部分依赖、传递依赖
(二)第二范式
在第一范式的基础上,非主属性对主属性不存在部分依赖
(三)第三范式
在第二范式的基础上,非主属性对主属性不存在传递依赖

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

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

相关文章

pyqt 自定义QTableWidget

自定义QTableWidget `import sys from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QWidget, QComboBox, QTabWidget, QTableWidget, QTableWidgetItem) from PyQt5.QtCore import Qt import re…

价值主体的技术实现:基于Free Transformer潜变量Z的AI元人文架构探索

基于Free Transformer的潜变量Z技术探索"价值主体行为"时,岐金兰揭示的两个核心担忧,指出了理论技术化过程中的关键风险。这些风险若不能得到妥善解决,将导致AI元人文构想从生机勃勃的价值生态系统,蜕变…

第二十二天

《程序员修炼之道:从小工到专家》阅读笔记:思维重塑 在技术迭代如浪潮的行业里,这本书并非罗列API的工具书,而是为程序员搭建了从“完成任务”到“创造价值”的思维桥梁。它最核心的启示在于:优秀的程序员,本质是…

Problemsetting

List of my problems其实我很不会出题, 所以不会常更新可能不会更新.Problem Difficulty[集训队互测 2023] 优惠购物 3300【UER #12】电子运动 2800【UNR #9】星图 2800【UNR #9】Sing 2900Canvas Painting ?cooperat…

记录一下我最近一年写的脚本,不知不觉近100个了!

记录一下我最近一年写的脚本,不知不觉近100个了! 一个系统初始化的脚本 @echo offecho 右击鼠标以管理员身份运行,按任意键退出 echo 开启远程桌面连接Wmic OS Get Caption | Findstr /i "7" >nul …

The 2025 Hunan Collegiate Programming Contest

Preface 不知道 VP 什么就找了场 QOJ 上最新的比赛,结果发现打的时候就我们一个队,全程无榜就很难受 而且这场的题目质量确实让人不敢恭维,一堆原题和典题,基本没有那种有意思的思维题 最后 9 of 11,剩下两个感觉…

List of my problems

其实我很不会出题, 所以不会常更新.Problem Difficulty[集训队互测 2023] 优惠购物 3300【UER #12】电子运动 2800【UNR #9】星图 2800【UNR #9】Sing 2900Canvas Painting ?cooperated (modified solution/idea):Pr…

歌声转换SVC主流方法原理剖析1 — DDSP-SVC

pre 本文SVC指的是歌声转换(Singing Voice Conversion (SVC)),例如常见且开源的 So-VITS-SVC, RVC, DDSP-SVC 关键词:歌声转换、声音克隆、音色 最早在23年刷到了惠惠的冬之花翻唱,惊为天人,一直对这块很感兴趣,…

SpringBoot整合邮件发送

一、邮件发送核心认知 1. 什么是邮件发送 邮件发送是应用程序中通过邮件服务器将信息传递给指定收件人的功能,支持纯文本、附件、图片、HTML 模板等多种形式。在 Spring Boot 中,借助 Spring 提供的邮件服务封装,可…

vyos syslog配置

设置syslog服务器和端口set system syslog host 10.1.1.2 port 514 设置记录全部内容 set system syslog console facility all 提交并保存 commit save稍后即可在日志服务器上看到日志。 如需记录到文件,使用下列命…

Unity3D URP中材质设置emission自发光但是没有辉光Bloom效果

如图,勾选了emission并且调高了强度,物体没有向外发光的辉光效果,原因是没有设置后处理,需要在Package Manager里下载post processing,然后新建Global Volume然后点开ProFile选中场景的profile即可,如果没有可以…

Ishibuchi教授与Lie Meng Pang博士受邀于本课题组开展学术交流与指导

2025年9月26日,本课题组成功举办了一场高水平的国际学术交流活动。此次活动邀请到了南方科技大学讲座教授、IEEE Fellow Hisao Ishibuchi 教授以及南方科技大学计算机科学与工程系的Lie Meng Pang 博士来院进行学术指…

【倒计时10天】第20届国际生物启发式计算:理论与应用会议(BIC-TA 2025)将于2025年11月7-9日在武汉召开!

【倒计时10天】各位老师好!第20届国际生物启发式计算:理论与应用会议(BIC-TA 2025)将于2025年11月7-9日在武汉召开!🔔 本次会议由华中科技大学主办,武汉科技大学、湖北省运筹学会协办。 会议已邀请四川大学Gar…

[TOOL] 二进制文件阅读与分析入门指南

[TOOL] 二进制文件阅读与分析入门指南$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");ChatGPT生成(2025年10月29日22:11:13)目录二进制文件阅读与分析入门…

[TOOL] hexdump: 二进制文件阅读指南

[TOOL] hexdump: 二进制文件阅读指南$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");DeepSeek生成(2025年10月29日22:03:39)目录Hexdump 二进制文件阅读指…

题解:CodeForces 715E Complete the Permutations

题意 对于两个排列 \(p,q\),定义它们的距离为将 \(p\) 变成 \(q\) 的最小操作次数,其中每次操作可以交换 \(p\) 中两个元素的位置。现在给定两个长度为 \(n\) 的排列 \(p,q\),其中一些位置被替换成了 \(0\)。对于每…

[TOOL] hexdump: 二进制文件分析指南

[TOOL] hexdump: 二进制文件分析指南$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");DeepSeek生成(2025年10月29日22:03:39)目录Hexdump 二进制文件分析指…

Day26-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\Threadcase

等待唤醒机制 生产者和消费者package Basic.src.com.Threadcase.Threadwaitnotify;public class Desk {/** 控制生产者和消费者的执行* *///桌子上是否有面条 0;没有面条 1:有面条public static int foodFlag = 0;…

题解:CF715E Complete the Permutations

题意 对于两个排列 \(p,q\),定义它们的距离为将 \(p\) 变成 \(q\) 的最小操作次数,其中每次操作可以交换 \(p\) 中两个元素的位置。现在给定两个长度为 \(n\) 的排列 \(p,q\),其中一些位置被替换成了 \(0\)。对于每…

日总结 20

YARN(Yet Another Resource Negotiator)是 Hadoop 生态中的核心集群资源管理与任务调度框架,旨在解耦 Hadoop 1.x 中 MapReduce 的计算与资源管理功能,通过 ResourceManager(全局资源管理)、NodeManager(节点资…