【发布时间】:2018-12-19 18:03:12
【问题描述】:
这个问题是对以下问题的跟进:
purposely union'ing NULLs for a training matrix.
在之前的帖子中,我提到了一家拥有工作技能表和员工技能表的公司。在本次讨论中,我们只使用其中两名员工...
jobskills + emplskills
job_code skill_desc skill_ID | empl_ID emplName job_code skill_ID
-------- ---------- -------- | ------- -------- -------- --------
APP Cut 10 | 396 Tom APP 10
APP Drill 20 | 396 Tom APP 30
APP Bend 30 | 426 Bob EXP 10
EXP Cut 10 | 426 Bob EXP 20
EXP Drill 20 | 426 Bob EXP 40
EXP Bend 30 | 426 Bob EXP 50
EXP Weld 40 |
EXP Turn 50 |
+
在jobskills表中,你会看到APP(学徒)职称需要3个技能——切割、钻孔、折弯(10、20、30)。同样,EXP(专家)职位需要 5 项技能(10 到 50)。
在emplskills 表中,您将看到 Tom 是一名学徒 (APP),他的职位应具备所有 3 项技能,但只有 2 项。他缺少钻孔技能 (20)。以同样的方式:作为专家 (EXP) 的 Bob 应该在其职位中拥有所有 5 项技能,但缺少 Bend 技能 (30)。
在上一篇文章中,@JuanCarlosOropeza 创建了这个查询(我重新定义了一些列),它通过外部连接每个 empl_ID 的 NULL 来列出员工拥有和不具备的所有技能。
WITH required_skills as
(
SELECT DISTINCT
e.empl_ID, e.job_code, j.skill_ID, j.skill_desc
FROM
emplskills e
JOIN
jobskills j ON e.job_code = j.job_code
)
SELECT
r.empl_ID, e.emplName, r.job_code, r.skill_ID, r.skill_desc
FROM
required_skills r
LEFT JOIN
emplskills e ON r.empl_ID = e.empl_ID
AND r.skill_ID = e.skill_ID;
上面的查询产生了我需要将员工的技能与他自己的职位进行比较的结果:
查询结果:
empl_ID emplName job_code skill_ID skill_desc
------- -------- -------- -------- ----------
396 Tom APP 10 Cut
396 Tom APP 20 Drill
396 {null} APP 30 Bend
426 Bob EXP 10 Cut
426 Bob EXP 20 Drill
426 {null} EXP 30 Bend
426 Bob EXP 40 Weld
426 Bob EXP 50 Turn
此查询的重点是使用此查询作为源视图的培训应用程序。如果用户根据 empl_ID 进行过滤,她可以查看 Tom (396) 并发现他缺少 Bend 技能 (30)
过滤 Tom(396)
empl_ID emplName job_code skill_ID skill_desc
------- -------- -------- -------- ----------
396 Tom APP 10 Cut
396 Tom APP 20 Drill
396 {null} APP 30 Bend
...现在是新问题:
在培训应用程序中,我需要将员工与任何职位进行比较。因此,我需要将每个可能的工作代码组合和每个可能的技能组合都与每个员工联系起来。
我真正需要的查询的期望结果是这样的:
empl_ID emplName job_code skill_ID skill_desc
------- -------- -------- -------- ----------
396 Tom APP 10 Cut
396 Tom APP 20 Drill
396 {null} APP 30 Bend
396 Tom EXP 10 Cut
396 Tom EXP 20 Drill
396 {null} EXP 30 Bend
396 {null} EXP 40 Weld
396 {null} EXP 50 Turn
426 Bob APP 10 Cut
426 Bob APP 20 Drill
426 Bob APP 30 Bend
426 Bob EXP 10 Cut
426 Bob EXP 20 Drill
426 {null} EXP 30 Bend
426 Bob EXP 40 Weld
426 Bob EXP 50 Turn
现在,当用户过滤时,他们可以将员工与不同职位的要求进行比较。对于 Tom the apprentice,Apprentice 标题上的原始过滤仍然有效:
Filter on Tom(396) and JOB CODE (APP)
empl_ID emplName job_code skill_ID skill_desc
------- -------- -------- -------- ----------
396 Tom APP 10 Cut
396 Tom APP 20 Drill
396 {null} APP 30 Bend
但是,如果正在考虑将 Tom 提升为 EXPERT,经理可以立即看到 Tom 缺乏哪些专家技能:
Filter on Tom(396) and JOB CODE (EXP)
empl_ID emplName job_code skill_ID skill_desc
------- -------- -------- -------- ----------
396 Tom EXP 10 Cut
396 Tom EXP 20 Drill
396 {null} EXP 30 Bend
396 {null} EXP 40 Weld
396 {null} EXP 50 Turn
有没有办法改变上面的查询来完成这个?到目前为止,我对你们提供的帮助非常感谢。这是我目前工作的现实挑战。我们有大约 150 名实际工厂工人,拥有 40 多个职称。其中一些职位有超过 3 打的相关技能 ID。
最后,我尝试使用上述查询创建 VIEW AS (),但无法获得正确的语法。新查询运行后,您能帮我将其转换为 CREATE VIEW 语句吗?
再次感谢, 约翰
【问题讨论】:
-
听起来你需要一个完整的外部联接。将查询转换为视图就像 CREATE VIEW MyView 一样简单 ....将您的查询放在这里...
-
@SeanLange 当我将上面的查询更改为
FULL OUTER JOIN而不是LEFT JOIN时,我得到与上面的查询相同的 8 行结果。 -
如上?显示了几个结果。
-
嗨@SeanLange,在帖子顶部附近有一个
WITH ... SELECT DISTINCT声明。该语句的正下方是一个 8 行查询结果。这也是我通过FULL OUTER JOIN更改得到的结果 -
@SeanLange 当我用
CREATE VIEW MY_VIEW AS (...)包装上述查询时,WITH出现语法错误,但没有解释。 ——约翰·约瑟夫
标签: sql-server null outer-join cartesian-product