2012-04-19 67 views
0

我有2代表的結構是這樣的:SQL - 加入2臺10倍

People 
---------- 
>ID, Name, Surname 

Projects 
---------- 
>ID, Assistant#1, Assistant#2, Assistant#3, Assistant#4, 
> Assistant#5, Assistant#6, Assistant#7, Assistant#8, Assistant#9, 
> Assistant#10, lot of other columns..... (every assistant column 
> contains an integer, the people ID) 

現在,我想查詢我的數據庫,並從項目表中的一行(讓我們假設有ID = 3行)包含項目表的所有列,特別是每個助理都用正確的名字和姓氏替換。 我設法做到了這一點(有很多連接),但是用我的小sql經驗,我的代碼看起來非常龐大,我相信有更好的方法來做到這一點。

在此先感謝。

+0

您的問題尚不清楚,請先編輯並使用示例數據和期望的結果將其清除 – 2012-04-19 10:43:54

+0

我這樣設計了我的表格,因爲實際上沒有10個同名的列,但每個列都有它自己的。但是,我是否應該重新整理我的桌子並添加另一個像許多用戶所說的?這有什麼好處?老實說,我不明白爲什麼......因爲我沒有經驗:) – Stefano 2012-04-19 11:32:12

+1

@Stefano - 因此,在關係數據庫中擁有更多關係表結構的好處是:1)只需要存儲什麼信息在那裏(如果只有一名助理,那麼你只有一行,而不是10列)。 2)你的連接不必太複雜,在我的文章中,前兩個查詢是針對你的表結構的,但是我的最後一個查詢可以用於所提出的結構(更直接,更容易閱讀)。 – Brett 2012-04-27 13:14:55

回答

0

因爲你設置了10多項的(可能)的助手,這決定了你將必須編寫代碼,以適應那些10個助手。這是可以做到的幾種方法:(沒有測試)

select * from projects proj 
left join people p1 on proj.assistant1 = p1.peopleid 
left join people p2 on proj.assistant2 = p2.peopleid 
left join people p3 on proj.assistant3 = p3.peopleid 
left join people p4 on proj.assistant4 = p4.peopleid 
left join people p5 on proj.assistant5 = p5.peopleid 
left join people p6 on proj.assistant6 = p6.peopleid 
left join people p7 on proj.assistant7 = p7.peopleid 
left join people p8 on proj.assistant8 = p8.peopleid 
left join people p9 on proj.assistant9 = p9.peopleid 
left join people p10 on proj.assistant10 = p10.peopleid 

否則,你可以做一些權謀與

select proj.projectID, 
(select * from people where peopleID = proj.assistant1), 
(select * from people where peopleID = proj.assistant2), 
(select * from people where peopleID = proj.assistant3), 
(select * from people where peopleID = proj.assistant4), 
(select * from people where peopleID = proj.assistant5), 
(select * from people where peopleID = proj.assistant6), 
(select * from people where peopleID = proj.assistant7), 
(select * from people where peopleID = proj.assistant8), 
(select * from people where peopleID = proj.assistant9), 
(select * from people where peopleID = proj.assistant10) 
from projects proj 

如果可能的話,它可能是最好重新構造你的數據表,並有一個助理映射到單一專案編號:

PeopleID, Name, Surname 

ProjectID, PeopleID 

因此,你可以做一內部聯接,你會返回一個排的每個助手:

select * from projects proj 
inner join people p 
on p.peopleID = proj.peopleid 
where proj.projectID = PROJECTID 
+0

這是完全正確的正如我想要的!謝謝! – Stefano 2012-04-19 12:28:38

+2

-1第一個查詢將不會按預期工作,因爲在列中存在空值的情況下行將不會返回。第二個選項中的子選擇效率非常低。 – Icarus 2012-04-19 12:54:23

+0

我認爲伊卡洛斯是正確的。如果其中任何一個查詢沒有找到任何記錄,基於多個內部聯接的查詢是否會失敗?我想你會想使用左外連接,以便在沒有找到匹配的字段中獲得NULL,同時仍然在找到匹配的字段中返回有效值。我也同意其他的海報,他們提到這是一種笨拙而普遍風險的做法,通過使用項目助理表進行規範化會有很大幫助。 – octern 2012-04-19 21:36:35

4

您的結構不清楚。我建議你爲項目創造一個離合器。

表:

Peoples people_id,people_name,people_surname

Projects PROJECT_ID,PROJECT_NAME

Clutch PROJECT_ID,people_id

+1

+1這是表示多對多關係的標準方式。雖然我會命名新的ProjectPeople表,以反映它與哪些其他表相關。離合器相當模糊。 – 2012-04-19 10:51:05

0

未測試:)

Select * from project pr 
left join people pe1 on pe1.peopleid = pr.astint1 
left join people pe2 on pe2.peopleid = pr.astint2 
left join people pe3 on pe3.peopleid = pr.astint3 
left join people pe4 on pe4.peopleid = pr.astint4 
left join people pe5 on pe5.peopleid = pr.astint5 
left join people pe6 on pe6.peopleid = pr.astint6 
left join people pe7 on pe7.peopleid = pr.astint7 
left join people pe8 on pe8.peopleid = pr.astint8 
left join people pe9 on pe9.peopleid = pr.astint9 
left join people pe10 on pe10.peopleid = pr.astint10 
where pr.projectid = 3 
+0

只有重大的調整,我會在這裏是左加入。如果一個記錄只有3個助手...這將不包括有任何單個(或多個)助手未填寫的記錄。 – DRapp 2012-04-19 11:47:51

+0

@DRAP:感謝您糾正我:),以及說(Y) – Suleman 2012-04-19 11:52:02

6
SELECT p.Name, p.Surname 
FROM People p 
CROSS JOIN Project j ON (p.PeopleID = j.Assistant1 OR 
p.PeopleID = j.Assistant2 OR 
p.PeopleID = j.Assistant3 OR 
.. etc) 
AND j.ProjectID = 3 

您的表現會很糟糕,但這是您爲設計可怕數據庫而付出的代價。更好的解決方案是通過分解的手段,一個項目,人們映射:

CREATE TABLE proj_people 
People_ID INT 
Project_ID INT 
0

也許更清潔的設計是:

People表:

People ID, Name, Surname 

ProjectAssistants表:

Project ID, Assistant Person ID 

項目表:

Project ID, lots of other columns (but no Assistant columns) 

然後,SQL變成類似:

SELECT pr.*, p.* 
FROM Projects pr 
JOIN ProjectAssistants p_a ON pr.ProjectID = p_a ProjectID 
JOIN People p ON p_a.AssistantPersonID = p.PeopleID 
WHERE ProjectID = X 
0

你的問題是,你正在試圖解決在數據庫級數據呈現的問題,這是很少一個好主意。你應該只有一張桌子,裏面只有兩個專欄作爲表格的主鍵。這將允許您將此表連接到助理表和項目表一次,並獲得您需要的所有結果。這也有利於您在未來支持更多的項目助手,而無需更改查詢以添加更多聯接。

總之,你應該有3個表:

Project 
Assistant 
ProjectAssistant (projectid,assistantid) 
0
你要調整你的表

。我討厭多次查看具有多個列的表,基本上是同一個事物。如果重組有3個表:

PeopleID | Name | Surname 

項目

ProjectID | ...other columns except Assistant 

Project_Person

ProjectID | PersonID 

這樣,你可以指定多個助理同一個項目,而不需要用於多個助理列。然後你可以使用類似的東西來獲得所需的結果:

SELECT proj.ProjectID, pers.Name, pers.Surname 
FROM Person pers 
INNER JOIN Project_Person pp ON pp.PersonID = pers.PersonID 
INNER JOIN Project proj ON proj.ProjectID = pp.ProjectID 

這不會返回單個行,但這不是SQL如何設計的。

0

如果你不想/不能改變表結構,那麼也許使用用戶定義的函數?

CREATE FUNCTION GET_ASS_NAME (n1 ASS_NO) RETURNS VARCHAR(50) DETERMINISTIC BEGIN DECLARE fullname VARCHAR(50); SELECT fullname = CONCAT(NAME, ' ', SURNAME) FROM PEOPLE WHERE ID = n1; RETURN fullname; END|

然後

select GET_ASS_NAME(1), GET_ASS_NAME(2), GET_ASS_NAME(3), ... from PROJECTS where ID = 3