问题描述
create table developers (name varchar2(30), skill varchar2(30)); create table projects (name varchar2(30), skill varchar2(30)); insert into developers values ('SMITH','ORACLE'); insert into developers values ('SMITH','JAVA'); insert into developers values ('ADAMS','JAVA'); insert into developers values ('ADAMS','C++'); insert into projects values ('MISSION MARS','JAVA'); insert into projects values ('MISSION MARS','C++'); insert into projects values ('MISSION IMPOSSIBLE','JAVA'); --QUERY: list out projects and eligible developers, for example Mission Mars -- requires knowledge of Java and C++ both, so developers having both skills -- like Adams is eligible for both the projects and both for MI-project. -- I have written a query but looking for something better: select d.name, p.name from developers d, projects p minus select tmp.d_name, tmp.name -- ineligible developers from (select * from projects, (select distinct name d_name from developers)) tmp left join developers d2 on (d2.skill = tmp.skill and d2.name = tmp.d_name) where d2.name is null;复制
专家解答
你如何定义 “更好”?快点?更容易阅读?
不管怎样,你试图的是关系分裂。这里有一种方法可以做到这一点,所以你只需要访问每个表一次,所以应该更快,更容易阅读 :)
它交叉加入表,然后按开发人员,项目和技能分组。你想要从这里的行,开发人员拥有项目的所有技能。表达式:
找到项目和开发人员技能匹配的行。如果这 (按项目和开发) 的总和 = 项目需要的技能数量,你有一个赢家:
您可以采用其他几种方法来实现关系划分。尽管可以说大多数都很难理解。
这是一篇文章,对它们进行了详尽的讨论 (它们使用SQL Server,但我想我们可以原谅它们;):
https://www.simple-talk.com/sql/learn-sql-server/high-performance-relational-division-in-sql-server/
请注意,前几个示例在您的情况下不起作用,因为您有多个项目。转到 “具有多个除数的关系划分” 部分,以获取与您的问题相匹配的解决方案。
不管怎样,你试图的是关系分裂。这里有一种方法可以做到这一点,所以你只需要访问每个表一次,所以应该更快,更容易阅读 :)
它交叉加入表,然后按开发人员,项目和技能分组。你想要从这里的行,开发人员拥有项目的所有技能。表达式:
sum(case when p.skill = d.skill then 1 else 0 end)复制
找到项目和开发人员技能匹配的行。如果这 (按项目和开发) 的总和 = 项目需要的技能数量,你有一个赢家:
create table developers (name varchar2(30), skill varchar2(30)); create table projects (name varchar2(30), skill varchar2(30)); insert into developers values ('SMITH','ORACLE'); insert into developers values ('SMITH','JAVA'); insert into developers values ('ADAMS','JAVA'); insert into developers values ('ADAMS','C++'); insert into projects values ('MISSION MARS','JAVA'); insert into projects values ('MISSION MARS','C++'); insert into projects values ('MISSION IMPOSSIBLE','JAVA'); select pname, dname, sum(sm), min(ct) from ( select d.name dname, p.name pname, p.skill, count(*) ct, sum(case when p.skill = d.skill then 1 else 0 end) sm from developers d cross join projects p group by d.name, p.name, p.skill ) group by pname, dname having sum(sm) = min(ct); PNAME DNAME SUM(SM) MIN(CT) MISSION MARS ADAMS 2 2复制
您可以采用其他几种方法来实现关系划分。尽管可以说大多数都很难理解。
这是一篇文章,对它们进行了详尽的讨论 (它们使用SQL Server,但我想我们可以原谅它们;):
https://www.simple-talk.com/sql/learn-sql-server/high-performance-relational-division-in-sql-server/
请注意,前几个示例在您的情况下不起作用,因为您有多个项目。转到 “具有多个除数的关系划分” 部分,以获取与您的问题相匹配的解决方案。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1310次阅读
2025-03-13 11:40:53
Oracle RAC ASM 磁盘组满了,无法扩容怎么在线处理?
Lucifer三思而后行
787次阅读
2025-03-17 11:33:53
Oracle+Deepseek+Dify 实现数据库数据实时分析
bicewow
715次阅读
2025-03-06 09:41:49
【ORACLE】ORACLE19C在19.13版本前的一个严重BUG-24761824
DarkAthena
573次阅读
2025-03-04 14:33:31
Oracle避坑指南|同名表导出难题:如何精准排除指定用户下的表?
szrsu
538次阅读
2025-03-05 00:42:34
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
462次阅读
2025-03-13 14:38:19
Ogg23ai高手必看-MySQL Innodb Cluster跟oracle的亲密接触
曹海峰
459次阅读
2025-03-04 21:56:13
【ORACLE】char类型和sql优化器发生的“错误”反应
DarkAthena
408次阅读
2025-03-04 23:05:01
Oracle 如何修改 db_unique_name?强迫症福音!
Lucifer三思而后行
350次阅读
2025-03-12 21:27:56
Oracle DataGuard高可用性解决方案详解
孙莹
311次阅读
2025-03-26 23:27:33