2010-07-04 64 views
2

考虑,如果你愿意,下表:在一项研究中加入与许多一对多的关系

Vacation Model http://imagetiger.org/images/vacatilrl.png

这似乎是一个奇怪的结构,但让我解释一下。这个结构的目标是创建一个列出所有人的报告,不包括那些在度假(为了简单起见,我们假设假期记录将只存在,如果一个人在度假。)

我有所有假期表都是因为“事件”表是“无关紧要”事件的一般用途表,而“假期”表包含更多详细信息,例如位置和日期。

我似乎无法弄清楚的是如何设计一个查询,包括Person.personId和Vacation.location,但只包含Person_Vacation中存在的那些personIds。或Person_Vacation中不存在的唯一personIds。

此外,这似乎是最好的方式来实现这个解决方案,设计明智吗?关于我可能做了什么错误或建议改进的任何想法?也许我只是不太善于沟通我的意图:事实证明,只有度假的人很容易,但我想进行反演,基本上所有人都不在度假。

+0

这似乎是两个完全简单的查询,查询得到你想要的结果...究竟是什么问题呢?你到目前为止尝试过什么,为什么失败?第一个似乎只是一个简单的JOIN ...你试过吗?第二个不太明显,但是是一个非常普遍的问题 - 记录存在于一个表格中,但不存在于另一个表格中。你知道不存在吗? – 2010-07-04 09:20:32

+0

请确切说出你想要查询的内容 - 就目前而言,你的需求可以用一种方式来解释,这意味着根本不需要外部连接。例如。 'SELECT * FROM Person JOIN Person_Event USING(personId)JOIN Vacation USING(eventId)'向您显示所有和只有那些休假的人(如果他们在多个休假时多次)。 – 2010-07-04 09:30:20

+0

@j_random_hacker:好的。 @马克拜尔斯:如果你不确定它是否在正确的轨道上,不要制定一个标题煽动一些解决方案。 – 2010-07-04 09:33:56

回答

5

设计方面我不明白你为什么需要Person_Vacation。如果我正确理解你的设计,每个假期都是一个事件(即“继承”),所以VacationPerson之间的连接可以通过Person_Event进行。然后查询将是:

SELECT P.PersonID, V.locaton 
FROM Person P, Vacation V, Person_Event PE 
WHERE P.personid = PE.personID AND PE.eventid = V.eventid 

人员在非假期活动:

SELECT P.PersonID, E.title 
FROM Person P, Person_Event PE, Event E 
WHERE P.personid = PE.personID AND PE.eventid = E.eventid 
AND E.eventID NOT IN (SELECT eventid FROM Vacation) 

人不任何假期:

SELECT P.PersonID, E.title 
FROM Person P, Person_Event PE, Event E 
WHERE P.personid = PE.personID AND PE.eventid = E.eventid 
AND P.personID NOT IN 
    (SELECT personid FROM Person_Event PE, Vacation V WHERE PE.eventid = V.eventid) 

在假期

人如果你想用你自己的设计,那么你必须决定是否您只能在Person_VacationPerson_VacationPerson_Event之间插入一个人的假期。如果你做前者,那么上面的查询会变得更简单一些。

但是我仍然会为我的设计投票,因为你实质上是在过早地分裂数据,以获得一些性能/简单性。从长远来看,这可能还没有回报。

+0

好点。虽然该模型确实使我查询的查询只需要3个表格(Person to Vacation通过Person_Vacation)而不是4(通过Person_Event的Person到Event,通过Event到Vacation)。 – 2010-07-04 09:25:21

+0

取决于您所查询的查询,请参阅上面的查询。如果你想继续沿着你自己的设计方向行事,你根本不需要任何NOT EXISTS/NOT IN谓词,因为Person_Vacation应该只包含人假期链接和Person_Event只包含非假期链接。虽然我不太喜欢这样的设计。 – 2010-07-04 09:33:18

+1

@wtfsven:如果在需要的事件(如标题)中有一些字段,则只需要查询4个表。否则,在查询中根本不需要Event表 - 您可以直接从Person_Event链接到Vacation。但即使你确实需要Event中的字段,4表连接也不需要担心。 – 2010-07-04 09:34:18

0

大概我没有完全理解你的数据库设计。如果Vocation也是一个事件,并且Person_Event表具有所有事件加强了人personId那么该表应该包含Person_Vacation的子集,并且可以消除它。此外,所有人都有时间职业,所以我觉得在某些表格中加入日期更合乎逻辑。

Nevetheless我怎么understend你的数据库设计,你可以用下面的一样

SELECT p.name, e.title 
FROM Person AS p 
    INNER JOIN Person_Event AS pe ON p.personId = pe.personId 
    INNER JOIN [Event] AS e ON pe.eventId = e.eventId 
    LEFT OUTER JOIN Vacation AS v ON e.eventId = v.eventId 
WHERE v.eventId IS NULL 
+0

从概念上讲,这应该是有效的,但这里的缺点是,对于Event中的每一行,Vacation中不一定有一行,所以WHERE v.eventId为NULL将导致它不返回任何内容,并且删除WHERE子句将返回假期中的那些子句。 – 2010-07-05 07:30:25