0

我有 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 的行),其中包含项目表的所有列,特别是将每个助手替换为正确的姓名和姓氏。我已经设法做到了这一点(有很多连接),但是以我的小 sql 经验,我的代码看起来非常庞大,我确信有更好的方法来做到这一点。

提前致谢。

4

8 回答 8

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
于 2012-04-19T10:43:33.757 回答
4

你的结构我不清楚。我建议您为项目创建一个离合器。

表:

Peoples people_id、people_name、people_surname

Projects 项目 ID,项目名称

Clutch project_id, people_id

于 2012-04-19T10:41:23.647 回答
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
于 2012-04-19T10:43:13.700 回答
0

也许更清洁的设计是:

人员表:

People ID, Name, Surname

项目助理表:

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
于 2012-04-19T10:44:42.630 回答
0

您的问题是您正在尝试在数据库级别解决数据表示问题,这很少是一个好主意。您应该有一个仅包含 projectid 和 assistantid 的表,将两列的组合作为表的主键。这将只允许您将此表连接到助手表和项目表一次,并获得您需要的所有结果。这也将具有允许您在未来支持更多项目助理的好处,而无需更改您的查询以添加更多连接。

总之,您应该有 3 个表:

Project
Assistant
ProjectAssistant (projectid,assistantid)
于 2012-04-19T10:45:21.000 回答
0

你想重组你的表。我讨厌多次看到具有多个列的表用于基本相同的事情。如果您重组为拥有 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 设计的工作方式。

于 2012-04-19T10:45:29.510 回答
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

于 2012-04-19T10:47:21.510 回答
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

如果可能,最好重新构建数据表的结构,并将单个助手映射到单个 projectID:

PeopleID, Name, Surname

ProjectID, PeopleID

因此,您可以只进行一次内连接,然后为每个助手返回一行:

select * from projects proj 
inner join people p 
on p.peopleID = proj.peopleid
where proj.projectID = PROJECTID
于 2012-04-19T10:50:31.590 回答