[英]sql - join 2 tables 10 times
我有2个结构如下的表:
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)
现在,我想查询我的数据库,并从Project表中获取一行(假定ID为3的行),该行包含Project表的所有列,尤其是用其正确的名称和姓氏替换了每个助手。 我已经设法做到了这一点(通过大量的连接),但是凭着我的一点SQL经验,我的代码看起来非常庞大,并且我相信有更好的方法可以做到这一点。
提前致谢。
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
我不清楚您的结构。 我建议您为项目创建一个离合器。
表格:
Peoples
people_id,people_name,people_surname
Projects
project_id,project_name
Clutch
project_id,people_id
未测试:)
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
也许更干净的设计是:
人物表:
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
您的问题是您正在尝试在数据库级别解决数据表示问题,但这很少是一个好主意。 您应该有一个仅包含projectid和assistantid的表,并将两列的组合作为该表的主键。 这将使您仅将此表连接到助手表和项目表一次,即可获得所需的所有结果。 这样的好处还在于,您将来可以在一个项目中为更多的助手提供支持,而不必更改查询以添加更多的联接。
总之,您应该有3个表:
Project
Assistant
ProjectAssistant (projectid,assistantid)
您想重组表。 我讨厌多次看到具有多列的表本质上是同一件事。 如果您重组为具有3个表:
人
PeopleID | Name | Surname
项目
ProjectID | ...other columns except Assistant
项目人员
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设计工作方式的方式。
如果您不想/不能更改表结构,那么可以使用用户定义的函数吗?
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
因为您将10个(可能的)助手设置为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
如果可能,最好重新组织数据表,并将一个助手映射到一个projectID:
PeopleID, Name, Surname
ProjectID, PeopleID
因此,您可以只执行一个内部联接,并且将为每个助手返回一行:
select * from projects proj
inner join people p
on p.peopleID = proj.peopleid
where proj.projectID = PROJECTID
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.