What-IF View Comparator 的 UNION NULLS 后续行动
Follow-up to UNION NULLS for What-IF View Comparator
此问题是以下问题的跟进:
在之前的话题中,我提到了一家公司的工作技能 table 和员工技能 table。对于此讨论,我们只使用其中两名员工...
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
table中,你会看到APP(学徒)职称需要3个技能——切割、钻孔、折弯(10、20、30)。同样,EXP(专家)职位需要 5 种技能(10 到 50)。
在emplskills
table中,你会看到汤姆是一个学徒(APP),他应该拥有他职称的所有3个技能,但只有2个。他缺少钻孔技能(20).以同样的方式:Bob,他是专家 (EXP),他的职称应该具备所有 5 项技能,但缺少弯曲技能 (30)。
在之前的 post 中,@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),发现他缺少弯曲技能 (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
...现在新问题:
在培训应用程序中,我需要将员工与任何职位进行比较。因此,我需要将每个员工与 job_codes 的每一种可能组合以及每一种可能的技能组合进行外部连接。
我真正需要的查询的期望结果是这样的:
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
现在,当用户筛选时,他们可以将员工与不同职位的要求进行比较。对于学徒汤姆,原先对学徒头衔的过滤仍然有效:
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
有没有办法改变上面的查询来完成这个?到目前为止,我对你们提供的帮助感激不尽。这是我目前工作中的现实挑战。我们在 40 多个职位中拥有大约 150 名实际工厂工人。其中一些职位有超过 3 打 skill_IDs 与之相关。
最后,我尝试使用上述查询创建 VIEW AS (),但语法不正确。新查询工作后,你能帮我把它转换成 CREATE VIEW 语句吗?
再次感谢,
约翰
您确实应该以可使用的格式发布数据。幸运的是,Juan Carlos Opreza 在您之前的问题中为您做到了这一点。我拿走了他的数据并从你的其他问题中删除了 "extra" 数据。
CREATE TABLE emplskills
([empl_ID] int, [emplName] varchar(3), [job_code] varchar(3), [skill_ID] int)
;
INSERT INTO emplskills
([empl_ID], [emplName], [job_code], [skill_ID])
VALUES
(396, 'Tom', 'APP', 10),
(396, 'Tom', 'APP', 20),
(426, 'Bob', 'EXP', 10),
(426, 'Bob', 'EXP', 20),
(426, 'Bob', 'EXP', 40),
(426, 'Bob', 'EXP', 50)
;
CREATE TABLE jobskills
([job_code] varchar(3), [skill_desc] varchar(5), [skill_ID] int)
;
INSERT INTO jobskills
([job_code], [skill_desc], [skill_ID])
VALUES
('APP', 'Cut', 10),
('APP', 'Drill', 20),
('APP', 'Bend', 30),
('EXP', 'Cut', 10),
('EXP', 'Drill', 20),
('EXP', 'Bend', 30),
('EXP', 'Weld', 40),
('EXP', 'Turn', 50)
;
现在我们有了一些具体而明确的东西可以使用,让我们看看它是如何工作的。由于左连接不起作用,因为您要在没有匹配项时填充 empl_ID,因此您需要一些不同的方法。解决这个问题的方法不止一种。我使用交叉连接生成了所有员工和工作技能的列表。这为我们提供了您的列表,我们可以在左连接中使用它。
我不得不说你需要仔细阅读规范化,因为这些结构相当痛苦。
select AllEmpSkills.empl_ID
, es.emplName
, js.job_code
, js.skill_ID
, js.skill_desc
from jobskills js
cross join
(
select distinct empl_ID from emplskills
) AllEmpSkills
left join emplskills es on es.empl_ID = AllEmpSkills.empl_ID
and es.skill_ID = js.skill_ID
order by AllEmpSkills.empl_ID
, js.job_code
, js.skill_ID
此问题是以下问题的跟进:
在之前的话题中,我提到了一家公司的工作技能 table 和员工技能 table。对于此讨论,我们只使用其中两名员工...
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
table中,你会看到APP(学徒)职称需要3个技能——切割、钻孔、折弯(10、20、30)。同样,EXP(专家)职位需要 5 种技能(10 到 50)。
在emplskills
table中,你会看到汤姆是一个学徒(APP),他应该拥有他职称的所有3个技能,但只有2个。他缺少钻孔技能(20).以同样的方式:Bob,他是专家 (EXP),他的职称应该具备所有 5 项技能,但缺少弯曲技能 (30)。
在之前的 post 中,@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),发现他缺少弯曲技能 (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
...现在新问题:
在培训应用程序中,我需要将员工与任何职位进行比较。因此,我需要将每个员工与 job_codes 的每一种可能组合以及每一种可能的技能组合进行外部连接。
我真正需要的查询的期望结果是这样的:
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
现在,当用户筛选时,他们可以将员工与不同职位的要求进行比较。对于学徒汤姆,原先对学徒头衔的过滤仍然有效:
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
有没有办法改变上面的查询来完成这个?到目前为止,我对你们提供的帮助感激不尽。这是我目前工作中的现实挑战。我们在 40 多个职位中拥有大约 150 名实际工厂工人。其中一些职位有超过 3 打 skill_IDs 与之相关。
最后,我尝试使用上述查询创建 VIEW AS (),但语法不正确。新查询工作后,你能帮我把它转换成 CREATE VIEW 语句吗?
再次感谢, 约翰
您确实应该以可使用的格式发布数据。幸运的是,Juan Carlos Opreza 在您之前的问题中为您做到了这一点。我拿走了他的数据并从你的其他问题中删除了 "extra" 数据。
CREATE TABLE emplskills
([empl_ID] int, [emplName] varchar(3), [job_code] varchar(3), [skill_ID] int)
;
INSERT INTO emplskills
([empl_ID], [emplName], [job_code], [skill_ID])
VALUES
(396, 'Tom', 'APP', 10),
(396, 'Tom', 'APP', 20),
(426, 'Bob', 'EXP', 10),
(426, 'Bob', 'EXP', 20),
(426, 'Bob', 'EXP', 40),
(426, 'Bob', 'EXP', 50)
;
CREATE TABLE jobskills
([job_code] varchar(3), [skill_desc] varchar(5), [skill_ID] int)
;
INSERT INTO jobskills
([job_code], [skill_desc], [skill_ID])
VALUES
('APP', 'Cut', 10),
('APP', 'Drill', 20),
('APP', 'Bend', 30),
('EXP', 'Cut', 10),
('EXP', 'Drill', 20),
('EXP', 'Bend', 30),
('EXP', 'Weld', 40),
('EXP', 'Turn', 50)
;
现在我们有了一些具体而明确的东西可以使用,让我们看看它是如何工作的。由于左连接不起作用,因为您要在没有匹配项时填充 empl_ID,因此您需要一些不同的方法。解决这个问题的方法不止一种。我使用交叉连接生成了所有员工和工作技能的列表。这为我们提供了您的列表,我们可以在左连接中使用它。
我不得不说你需要仔细阅读规范化,因为这些结构相当痛苦。
select AllEmpSkills.empl_ID
, es.emplName
, js.job_code
, js.skill_ID
, js.skill_desc
from jobskills js
cross join
(
select distinct empl_ID from emplskills
) AllEmpSkills
left join emplskills es on es.empl_ID = AllEmpSkills.empl_ID
and es.skill_ID = js.skill_ID
order by AllEmpSkills.empl_ID
, js.job_code
, js.skill_ID