2013-04-05 25 views
0

我的數據庫中有四個表格: 包含ID(PK)和名稱的人員。包含ID(PK),PID(FK),技能(FK)和SkillLevel(FK)的Person_Skill。 包含ID(PK)和SkillLabel的技能。 包含ID(PK)和名稱的SkillLevel。我應該在SQL中使用哪種加入方式

每個技能有從0到7

現在我想顯示所有的人都有的技術水平(附上skilllevel = 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級的原因是因爲人表只包含從1級到7級的技能,但我不確定這個。我從其他人那裏得到了數據庫。如果我的假設是正確的,是否有這樣做?獲得技能表中的所有技能並顯示該人的技能水平(包括skillllevel = 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 
+0

你可以給樣品記錄? – 2013-04-05 15:55:27

回答

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 with Demo

如果你想包括所有 Skills 0-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 

編輯,沒有看到任何數據,它很難確定。但是如果你想檢索所有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 

+0

我改變了我的查詢,與此類似。結果編號與上面相同(不包括技能等級= 0)此人的所有技能名稱也是相同的。 – Michael 2013-04-05 16:13:07

+0

@Michael我的建議是使用每張表中的一些示例數據編輯原始帖子。 – Taryn 2013-04-05 16:14:11

+0

@Michael查看我的編輯,我更新了查詢以包含'SkillLevel'表。 – Taryn 2013-04-05 16:35:23

0

你想使用LEFT JOIN,當tableAtableb內加入將從tableA返回所有記錄,而不管是否有來自比賽tableB

因此,如果沒有人擁有0的技能,那麼您仍然會收回所有的person 記錄。

0

INNER JOIN只會返回雙方都有匹配的行。所以在你的代碼中,如果一個人沒有0級的技能,它就不會被返回。

你可以做一個LEFTRIGHT連接,它們可以從左側或右側獲取表中的所有行。我認爲你可能想要使用一個左連接,但不知道更多關於你的模式,很難說肯定。見在不同的連接類型提供給問題Left join and Left outer join in SQL Server更多細節上的差異,答案