0

我的数据库中有四个表:包含 ID(PK) 和名称的人员。Person_Skill 包含 ID(PK)、PID(FK)、Skill(FK) 和 SkillLevel(FK)。包含 ID(PK) 和 SkillLabel 的技能。包含 ID(PK) 和名称的技能级别。

每个技能都有从0到7的等级

现在我想显示该人拥有的所有技能(包括技能级别 = 0)

Select
   [dbo].Person.Name as Name,
   [Skill].SkillLabel as SkillName,
   [Person_Skill].[SkillLevel] as SkillLevel
From
   ([dbo].Person inner join [dbo].[Person_Skill] ON [dbo].[Person_Skill].PID= Person.ID)
   inner join [dbo].[Skill] ON [dbo].[Person_Skill].Skill=Skill.ID

上面的代码只显示了这个人从1级到7级的技能。

我相信我只获得 1 到 7 级技能的原因是因为 person 表只包含 1 到 7 级的技能,但我不确定这一点。我从其他人那里得到了数据库。如果我的假设是正确的,有没有办法做到这一点?获取技能表中的所有技能并显示该人拥有的技能等级(包括技能等级=0)。

Sample Data:
Person
ID    Name
----------
1     Michael
2     Alex

Person_Skill
ID    PID  SkillID Skill_Level
5     1     10          5
6     2     11          1
7     1     12          7
8     1     13          5

Skill
ID    Name
10    java
11    C++
12    HTML
13    ASP
14    C
15    .NET
16    C#
17    Objective

The expect results are;
Name    SkillName SkillLevel
----------------------------
Alex    java        0
Alex    C++         1
Alex    HTML        0
Alex    ASP         0
Alex    C           0
Alex    .NET        0
Alex    C#          0
Alex    Objective C 0
Michael    java      5
Michael    C++       0
Michael    HTML      7
Michael    ASP       0
Michael    C         0
Michael    .NET      5
Michael    C#        0
Michael    Objective C0

当前查询只输出

Alex    C++         1
Michael    java      5
Michael    HTML      7
Michael    .NET      5
4

3 回答 3

2

编辑,如果您想返回每个人的所有技能名称,那么您将需要使用:

select d.p_name,
  d.s_name SkillName,
  coalesce(ps.Skill_Level, 0) Skill_Level
from
(
  select p.id p_id, p.name p_name, s.id s_id, s.name s_name
  from person p
  cross join skill s
) d
left join person_skill ps
  on d.p_id = ps.pid
  and d.s_id = ps.skillid
left join skill s
  on ps.skillid = s.id

请参阅带有演示的 SQL Fiddle

如果要包括所有Skills0-7,则需要使用LEFT JOIN. 您的查询将类似于以下内容:

select p.Name as Name,
   s.SkillLabel as SkillName,
   ps.[SkillLevel] as SkillLevel
from [dbo].[Skill] s
left join [dbo].[Person_Skill] ps
  on ps.Skill=s.ID
left join [dbo].Person p
  on ps.PID = p.ID

编辑,没有看到任何数据很难确定。但是,如果您想检索 all SkillLevels,则需要包含该表。您可能需要使用:

select 
  p.Name as Name,
  s.SkillLabel as SkillName,
  sl.[Name] as SkillLevel
from SkillLevel sl
left join [dbo].[Person_Skill] ps
  on ps.SkillLevel=sl.ID
left join [dbo].[Skill] s
  on ps.Skill = s.Id
left join [dbo].Person p
  on ps.PID = p.ID

于 2013-04-05T15:56:37.357 回答
0

您可能希望使用LEFT JOINwhich when tableAis inner join ontableb将返回所有记录,tableA无论是否存在匹配项tableB

因此,如果没有具有 技能的人0,您仍然可以取回所有person记录。

于 2013-04-05T15:53:29.087 回答
0

AnINNER JOIN只会返回双方都匹配的行。因此,在您的代码中,如果一个人没有 0 级技能,则不会返回。

您可以执行 a LEFTor RIGHTjoin ,然后这些从左侧或右侧的表中获取所有行。我认为您可能想使用左连接,但是如果不了解更多有关您的架构的信息,就很难确定。有关不同连接类型差异的更多详细信息,请参阅SQL Server 中的左连接和左外连接问题的答案

于 2013-04-05T15:55:01.177 回答