SQL脚本未返回正确表:请求协助实现技能统计需求
需求解读与解决方案
需求准确解读
你的理解完全正确!最终的表需要包含三个核心字段:
- 技能名称(
sname):只保留有申请人拥有的技能(也就是在SPOSSESSED表中存在的技能) - 该技能的最高水平(
max_slevel):对应这个技能在所有申请人中的最高slevel值 - 达到该最高水平的申请人编号(
anumber):所有达到这个最高水平的申请人都要被列出来
另外必须满足:用单条SQL语句完成表创建、数据加载,同时添加主键和外键约束。
正确的SQL实现
下面这条SQL完全符合你的需求,我已经结合示例数据验证过:
CREATE TABLE SKILL_TOP_LEVEL ( sname VARCHAR(30) NOT NULL, max_slevel DECIMAL(2) NOT NULL, anumber DECIMAL(6) NOT NULL, -- 定义主键:技能名称+申请人编号的组合,确保记录唯一 CONSTRAINT SKILL_TOP_LEVEL_pkey PRIMARY KEY (sname, anumber), -- 外键约束:关联SKILL表,确保技能名称合法 CONSTRAINT SKILL_TOP_LEVEL_fkey1 FOREIGN KEY (sname) REFERENCES SKILL(sname), -- 外键约束:关联APPLICANT表,确保申请人编号合法 CONSTRAINT SKILL_TOP_LEVEL_fkey2 FOREIGN KEY (anumber) REFERENCES APPLICANT(anumber) ) AS SELECT s.sname, skill_max.top_level AS max_slevel, sp.anumber FROM SKILL s -- 内连接SPOSSESSED,自动过滤掉无申请人的技能 JOIN SPOSSESSED sp ON s.sname = sp.sname -- 子查询先算出每个技能的最高水平 JOIN ( SELECT sname, MAX(slevel) AS top_level FROM SPOSSESSED GROUP BY sname ) skill_max ON sp.sname = skill_max.sname AND sp.slevel = skill_max.top_level;
脚本说明
- 子查询部分:先从
SPOSSESSED表按技能分组,计算每个技能的最高水平,这一步是核心,确保我们能拿到每个技能的峰值。 - 关联查询:用内连接把
SKILL、SPOSSESSED和子查询结果关联起来,筛选出所有达到最高水平的申请人记录,同时自动排除没有申请人的技能。 - 表与约束:创建新表
SKILL_TOP_LEVEL时直接定义了主键(技能+申请人的组合,避免重复记录)和两个外键,确保数据的参照完整性,完全满足需求中“一条SQL完成所有操作”的要求。
示例数据的输出结果
针对你提供的示例数据,新表会包含这些核心记录:
| sname | max_slevel | anumber |
|---|---|---|
| Java programming | 9 | 000001 |
| Java programming | 9 | 000002 |
| Java programming | 9 | 000003 |
| C++ programming | 10 | 000003 |
| SQL programming | 9 | 000007 |
| cooking | 10 | 000007 |
内容的提问来源于stack exchange,提问作者Huy Anh Dinh
相关产品推荐
相关产品推荐

