Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 假设视图比较器的联合空值的后续操作_Sql Server_Null_Outer Join_Cartesian Product - Fatal编程技术网

Sql server 假设视图比较器的联合空值的后续操作

Sql server 假设视图比较器的联合空值的后续操作,sql-server,null,outer-join,cartesian-product,Sql Server,Null,Outer Join,Cartesian Product,这个问题是对以下问题的后续: 在上一篇文章中,我提到了一家拥有工作技能表和员工技能表的公司。在本次讨论中,我们只使用两名员工 jobskills + emplskills job_code skill_desc skill_ID | empl_ID emplName job_code skill_ID -------- ---------- -------- | ------- -------- -------- ----

这个问题是对以下问题的后续:

在上一篇文章中,我提到了一家拥有工作技能表和员工技能表的公司。在本次讨论中,我们只使用两名员工

           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表中,您将看到应用程序学徒职位需要3项技能-切割、钻孔和弯曲10、20、30。同样,EXP专家职称需要5项技能10至50

在EmploySkills表中,您将看到Tom是一个学徒应用程序,他应该拥有职位的所有3项技能,但只有2项。他缺少钻井技术。同样的方式:鲍勃是一名经验丰富的专家,在他的职位上,他应该拥有全部5项技能,但缺少弯曲技能30项

在上一篇帖子中,@JuanCarlosOropeza创建了这个查询。我重新定义了一些列,这些列将每个员工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
此查询的要点是将此查询用作源视图的培训应用程序。如果用户过滤员工ID,她可以查看Tom 396,发现他缺少弯曲技能30

Tom396上的过滤器

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
现在,当用户筛选时,他们可以将员工与不同职位的要求进行比较。对于学徒汤姆来说,学徒头衔的原始过滤仍然有效:

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提升为专家,经理可以立即了解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个。其中一些职位有超过30多种与之相关的技能ID

最后,我尝试使用上面的查询创建视图,但无法获得正确的语法。在新查询运行之后,您能帮助我将其转换为CREATEVIEW语句吗

再次感谢,
John

你真的应该以可消费的格式发布数据。幸运的是,胡安·卡洛斯·奥普雷扎在你之前的问题中为你做到了这一点。我拿走了他的,并从你的另一个问题中删除了额外的数据

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)
;
现在,我们有了一些具体和明确的工作,让我们看看这可能会如何工作。由于在没有匹配项的情况下填充emp_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

听起来你需要一个完整的外部连接。将查询转换为视图非常简单,只需创建视图MyView即可…将您的查询放在此处…@SeanLange当我将上面的查询更改为完全外部联接而不是左联接时,我会得到与上面的查询相同的8行结果。与上面的哪个相同?这里显示了几个结果。Hi@SeanLange,靠近帖子顶部有一个带有。。。选择DISTINCT语句。该语句的正下方是一个8行查询结果。这是我得到的结果,以及与充分的外部连接change@SeanLange当我用CREATE VIEW将上述查询包装为我的\u视图时。。。我在WITH上发现语法错误,但没有解释约翰·约瑟夫太棒了!我放弃了订单条款,提出了一个观点。工作完美。再次非常感谢。但最重要的是你明白它为什么有效。不要犹豫,问问你是否有你没有得到的部分。很高兴你能使用这个。好的,我看到十字架是雇员ID和技能ID的所有可能的组合。然后左键连接。我不太擅长复合选择,所以再次感谢。是的,听起来你明白了。看到这样的事情并理解它们将有助于你自己想出如何变戏法D