| 雇员标识|技能水平|技能标识|
| - ------|- ------|- ------|
| 小行星1550|初学者|五百六十|
| 小行星6540|初学者|五百六十|
| 小行星2354|中级|五百六十|
| 小行星665|高级|五百六十|
| 小行星1550|高级|七百八十|
| 小行星6540|初学者|七百八十|
| 小行星1550|中级|七百八十|
| 小行星2354|中级|七百八十|
| 小行星1550|中级|四百五十|
| 小行星6540|初学者|六五四|
| 小行星8888|初学者|五百六十|
| 小行星665|高级|四百五十五|
| 小行星1550|高级|一百一十|
| 小行星6540|高级|八八五|
| 小行星2354|高级|九八零|
| 小行星665|中级|八七零|
我只想得到具有特定技能和他们各自特定水平的员工;我会得到这样的结果:
| 雇员标识|技能水平|技能标识|
| - ------|- ------|- ------|
| 小行星1550|初学者|五百六十|
| 小行星1550|中级|七百八十|
我尝试了这个方法,但显然它不是我想要的,因为它有一个包含的OR
,所以我不知道应该使用哪个运算符/技术
select *
from employees_skills mec
where (mec.skill_id, mec.skill_level) = (560, 'BEGINNER')
or (mec.skill_id, mec.skill_level) = (780, 'INTERMEDIATE')
如果我这样做的一套两个技能(和他们的resp.水平),我将能够这样做更多。
- EDIT**:不应返回雇员2354(即使他们是560的初学者,但他们不具备其他技能780和/或他们不是中级)。
我希望员工具备WHERE条件下的所有技能及其相应级别
2条答案
按热度按时间jyztefdp1#
你需要一些额外的括号():
这将创建一个元组,这就是您要查找的内容。
kokeuurv2#
第一个问题是您正在查找组合技能组合(423,'中级'),但是该组合 * 在您的数据中不存在 *。
您的场景呈现出一个有趣的两难境地:你的结果必须有多个skill_id,skill_level组合,但是一行只能有一个skill_id,skill_level的值集。那么如何将多行与多个值进行比较 * 在同一时间 *。你可以使用一系列的
and exists (select ...)
。但是,这需要知道组合的数量或者动态sql来构造exist子句。另一个,是使用数组比较,特别是array containment operatoranyarray @〉anyarray → boolean第一个数组是否包含第二个数组,也就是说,第二个数组中出现的每个元素是否等于第一个数组中的某个元素?
首先生成包含skill_id和skill_level的UDT。然后创建一个表(可以是临时表)以包含UDT的数组。
完成上述操作后,现在可以按雇员聚合雇员技能集,然后使用包含操作符(
@>
)将该聚合加入到目标技能中。(see demo)注意:最后的查询可能可以重构和简化,但是我想展示它开发过程中的每一步。
编辑问题:没有更简单/更快的方法吗?
正如我所说的,它可能可以被减少,但是仔细观察,您会发现
( select es ... ) s1
部分是唯一实际访问数据库的部分,其他部分只是对上一步中已经存在于内存中的结果进行简单转换,因此不需要额外的实际i/o。如前所述,您可以使用一组and exists (select ...
,但所需的选择数与(mec.skill_id, mec.skill_level)
条件集的数量相同(5个条件,然后5个选择,10个条件,然后10个选择,50个条件,您明白了吧)。每个条件访问数据库时可能会有额外的i/o。无论条件的数量如何,上述内容都不会更改(5,10,50查询保持不变)。同时,将简单的转换组合成一个大的转换会很快变得复杂,仅仅将它们串在一起几乎不起作用。显然,我的意见是 * 没有更简单/更快的方法吗?*否。一个选项可能是将查询隐藏在SQL函数中。