京公网安备 11010802034615号
经营许可证编号:京B2-20210330
来源:数据STUDIO
作者:云朵君
查询"01"课程比"02"课程成绩高的学生信息及课程分数
分析
第一步:根据需要查询的最终结果确认所需用到的表:"学生信息及课程分数",需要用到学生信息表与成绩表;
第二步:确认条件:"01"课程比"02"课程成绩高的学生,需要先分别查出"01"课程的成绩与"02"课程,再根据条件"成绩更高"筛选出学生;
#查询01课程的成绩 SELECT * FROM sc WHERE c_id='01';
#查询02课程的成绩 SELECT * FROM sc WHERE c_id='02';
第三步:查询:根据第二步筛选出的学生,查询出对应学生的"学生信息及课程分数"。
语句
SELECT stu.*,sc.c_id,sc.score FROM (SELECT * FROM sc WHERE c_id='01') t1 JOIN (SELECT * FROM sc WHERE c_id='02') t2 ON t1.s_id=t2.s_id JOIN stu ON t1.s_id=stu.s_id JOIN sc ON stu.s_id=sc.s_id WHERE t1.score>t2.score;
结果
s_ids_names_births_sexc_idscore02钱电1990-12-21男017002钱电1990-12-21男026002钱电1990-12-21男038004李云1990-08-06男015004李云1990-08-06男023004李云1990-08-06男0320
如果要求课程分数需要"课程名称"与"对应分数",则还需要跟课程表连接以显示课程名及分数。
语句
SELECT stu.*,co.c_name,sc.score FROM (SELECT * FROM sc WHERE c_id='01') t1 JOIN (SELECT * FROM sc WHERE c_id='02') t2 ON t1.s_id=t2.s_id JOIN stu ON t1.s_id=stu.s_id JOIN sc ON stu.s_id=sc.s_id JOIN co ON sc.c_id=co.c_id WHERE t1.score>t2.score;
结果
s_ids_names_births_sexc_namescore02钱电1990-12-21男语文7004李云1990-08-06男语文5002钱电1990-12-21男数学6004李云1990-08-06男数学3002钱电1990-12-21男英语8004李云1990-08-06男英语20
以上例子中先分别查出"01"课程的成绩与"02"课程,再根据查询出的结果去查询对应学生信息及课程成绩,即用到本节将要介绍的子查询。
在SELECT语句中,子查询总是从内向外处理。在处理上面的SELECT语句时,MySQL实际上执行了两个操作。
首先,它执行下面的查询:
SELECT t1.* FROM (SELECT * FROM sc WHERE c_id='01') t1 JOIN (SELECT * FROM sc WHERE c_id='02') t2 ON t1.s_id=t2.s_id WHERE t1.score>t2.score;
此时得到两个学生编号s_id等于02和04表格:
s_idc_idscore020170040150
然后,将得到的表格t与另外两个表格连接后再查询。
SELECT stu.*,sc.c_id,sc.score FROM t JOIN stu ON t1.s_id=stu.s_id JOIN sc ON stu.s_id=sc.s_id
其实这里也分了两步:
SELECT stu.*,sc.c_id,sc.score FROM t JOIN stu ON t1.s_id=stu.s_id
结果:
s_ids_names_births_sexc_idscore02钱电1990-12-21男017004李云1990-08-06男0150
这里只得到了这两个学生的课程1的成绩,结果需要查询到这两个学生所有课程的成绩,因此需要将上述得到的表格tt再与成绩表连接。
SELECT stu.*,sc.c_id,sc.score FROM tt JOIN sc ON stu.s_id=sc.s_id
格式化SQL 包含子查询的SELECT 语句难以阅读和调试,特别是它们较为复杂时更是如此。如上所示把子查询分解为多行并且适当地进行缩进,能极大地简化子查询的使用。
查询没学过"张三"老师授课的同学的信息
首先需要查询出"张三"老师授课信息:
SELECT stu.s_id FROM te LEFT JOIN co ON te.t_id=co.t_id LEFT JOIN sc ON co.c_id=sc.c_id LEFT JOIN stu ON sc.s_id=stu.s_id WHERE t_name='张三';
得到"张三"老师授课信息s_id为01,02,03,04,05,07。然后,这两个值以 NOT IN 操作符要求的逗号分隔的格式传递给外部查询的 WHERE 子句。
外部查询变成:
SELECT * FROM stu WHERE s_id NOT IN (01,02,03,04,05,07);
结果:
s_ids_names_births_sex06吴兰1992-03-01女08王菊1990-01-20女
可见,在 WHERE子句中使用子查询能够编写出功能很强并且很灵活的SQL语句。对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。
列必须匹配 在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE 子句中相同数目的列。通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列。
使用子查询的另一方法是创建计算字段。
查询每位学生选修的课程数
首先可使用 SELECT COUNT(*)对表中的行进行计数,并且通过提供一条WHERE子句来过滤某个特定的学生,可仅对该学生的课程进行计数。
SELECT COUNT(c_id) FROM sc WHERE s_id = '01';
为了对每个学生执行COUNT(*)计算,应该将COUNT(*)作为一个子查询。
SELECT *, (SELECT COUNT(c_id)
FROM sc
WHERE sc.s_id = stu.s_id) AS cos FROM stu;
结果:
s_ids_names_births_sexcos01赵雷1990-01-01男302钱电1990-12-21男303孙风1990-05-20男304李云1990-08-06男305周梅1991-12-01女206吴兰1992-03-01女207郑竹1992-04-21女208王菊1990-01-20女0
这条SELECT语句对customers表中每个学生返回5列:s_id,s_name,s_birth,s_sex和cos。cos是一个计算字段,它是由圆括号中的子查询建立的。该子查询对检索出的每个学生执行一次。在此例子中,该子查询执行了8次,因为检索出了8个学生。
子查询中的 WHERE子句使用了完全限定列名,任何时候只要列名可能有多义性,就必须使用这种语法(表名和列名由一个句点分隔)。如果不使用完全限定的列名会与本身匹配。
逐渐增加子查询来建立查询 用子查询测试和调试查询很有技巧性,特别是在这些语句的复杂性不断增加的情况下更是如此。用子查询建立(和测试)查询的最可靠的方法是逐渐进行,这与MySQL处理它们的方法非常相同。首先,建立和测试最内层的查询。然后,用硬编码数据建立和测试外层查询,并且仅在确认它正常后才嵌入子查询。这时,再次测试它。对于要增加的每个查询,重复这些步骤。这样做仅给构造查询增加了一点点时间,但节省了以后(找出查询为什么不正常)的大量时间,并且极大地提高了查询一开始就正常工作的可能性。
数据库建立即数据导入准备
-- 创建数据库school CREATE DATABASE school; -- 选择进入school数据库 USE school; -- ------------建表导数------------- -- 创建stu CREATE TABLE stu(
s_id VARCHAR(10) PRIMARY KEY,
s_name VARCHAR(10) NOT NULL,
s_birth DATE,
s_sex VARCHAR(10)) -- 导入数据 INSERT INTO stu VALUES ('01' , '赵雷' , '1990-01-01' , '男'),
('02' , '钱电' , '1990-12-21' , '男'),
('03' , '孙风' , '1990-05-20' , '男'),
('04' , '李云' , '1990-08-06' , '男'),
('05' , '周梅' , '1991-12-01' , '女'),
('06' , '吴兰' , '1992-03-01' , '女'),
('07' , '郑竹' , '1992-04-21' , '女'),
('08' , '王菊' , '1990-01-20' , '女'); SELECT * FROM stu; -- 检查数据 SELECT COUNT(*) FROM stu; -- 检查总行数 -- 创建co CREATE TABLE co(
c_id VARCHAR(10) PRIMARY KEY,
c_name VARCHAR(10),
t_id VARCHAR(10)); -- 导入数据 INSERT INTO co VALUES ('01' , '语文' , '02'),
('02' , '数学' , '01'),
('03' , '英语' , '03'); SELECT * FROM co; -- 检查数据 SELECT COUNT(*) FROM co; -- 检查总行数 -- 创建te CREATE TABLE te(
t_id VARCHAR(10) PRIMARY KEY,
t_name VARCHAR(10)); -- 导入数据 INSERT INTO te VALUES ('01' , '张三'),
('02' , '李四'),
('03' , '王五'); SELECT * FROM te; -- 检查数据 SELECT COUNT(*) FROM te; -- 检查总行数 -- 创建sc CREATE TABLE sc(
s_id VARCHAR(10),
c_id VARCHAR(10),
score int); -- 导入数据 INSERT INTO sc VALUES ('01' , '01' , 80),
('01' , '02' , 90),
('01' , '03' , 99),
('02' , '01' , 70),
('02' , '02' , 60),
('02' , '03' , 80),
('03' , '01' , 80),
('03' , '02' , 80),
('03' , '03' , 80),
('04' , '01' , 50),
('04' , '02' , 30),
('04' , '03' , 20),
('05' , '01' , 76),
('05' , '02' , 87),
('06' , '01' , 31),
('06' , '03' , 34),
('07' , '02' , 89),
('07' , '03' , 98); SELECT * FROM sc; -- 检查数据 SELECT COUNT(*) FROM sc; -- 检查总行数
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
【核心关键词】客户、数据分析、指标体系、数据采集、数据指标、业务数据、分析思路、业务需求、分析方法 【专访摘要】本次 CDA ...
2026-07-24在数据分析、业务建模与数字化运营体系中,原始业务数据普遍存在缺失、重复、异常、口径不一致等质量问题,直接用于分析与建模会 ...
2026-07-24 很多数据分析师能熟练计算均值、标准差,但当被问到“如何用一张图让业务方3秒内看懂核心结论”“面对不同数据类型该怎么选 ...
2026-07-24在数据驱动的精细化运营体系中,指标是业务判断、效果复盘、策略优化的核心依据。随着企业数据化程度提升,指标数量持续膨胀,但 ...
2026-07-23在用户运营与产品增长体系中,留存是衡量产品真实价值与用户粘性的核心标尺,也是决定用户生命周期价值、获客投产比的底层因素。 ...
2026-07-23 很多数据分析师精通Excel、SQL、Python等工具,但当被问到“面对一个具体的业务问题,该用什么分析方法”“描述性分析和诊断 ...
2026-07-23【核心关键词】埋点、产品、互联网、数据库、决策、数据分析、产品经理、商业模式、移动互联网、指标体系、运营模块、大数据平 ...
2026-07-22在高并发、大数据量的业务系统中,单表数据量达到千万级甚至亿级后,会出现查询性能骤降、索引维护成本飙升、存储扩容困难等问题 ...
2026-07-22 很多企业团队并非缺乏指标,而是陷入“指标失控”:仪表盘上堆满实时跳动的数据,却无法回答“当前瓶颈在哪、下一步该做什么 ...
2026-07-22在金融风控、企业运营、行业研究等数据分析场景中,大量数据以面板数据形态存在:例如多家分支机构连续多个季度的风险指标、多位 ...
2026-07-21 很多数据分析师每天都在计算指标、制作报表,但当被问到“什么叫指标数据元”“指标数据标准包含哪些核心维度”“指标数据质 ...
2026-07-21一、活动介绍 2026暑期CDA备考冲刺季,为想利用假期拿证的你量身打造。考点胶囊内容搭配多重硬核福利,让你在旅行、实习、居家 ...
2026-07-21金融行业的运营风险贯穿业务全流程,涵盖交易欺诈、操作违规、流程漏洞、合规偏差、客户信用异常等多元场景,是银行、保险、证券 ...
2026-07-17财产保险作为金融行业的核心板块,涵盖车险、家财险、责任险、企财险等多元品类,是个人与企业抵御财产风险、经营风险的重要保障 ...
2026-07-17 很多数据分析师能熟练写SQL、做透视表,但当被问到“数据是从哪里来的?经过哪些加工才进入数据仓库?ETL具体做了什么?”时 ...
2026-07-17【核心关键词】模块、餐饮、客户、门店、企业、订单、供应链、多样化、产品、生产计划、数据分析、生产管理、物料管理、业务分 ...
2026-07-16在数字化分析时代,原始数据本身不具备业务价值,只有通过科学的统计学方法加工、拆解、验证与解读,才能挖掘数据背后的规律、差 ...
2026-07-16 很多数据分析师能熟练地写SQL、做透视表、算描述性统计,但当被问到“如何预测用户流失概率”“如何归因销量下滑的关键因素 ...
2026-07-16在描述性统计分析、数据预处理、异常值排查与多组数据分布对比工作中,箱线图(Box Plot)是应用最广泛的可视化与统计工具之一。 ...
2026-07-15在企业数据存储、业务统计与数据分析工作中,绝大多数业务数据都带有时间维度属性,例如订单创建时间、用户注册时间、支付完成时 ...
2026-07-15