0

我尝试编写一个 SQL 查询(使用完全外连接),它从三个通过 n:m-relationships 相互关联的表创建一个完整的结果集。

初始情况是具有三个实体的规范化数据模型:person、artifact 和 location。每个实体都通过由交集表表示的 m 关系与每个其他实体相关。

person { person_id, ... }  
artifact { artifact_id, ... }
location { location_id, ... }

rel_person_artifact { person_id, artifact_id, role_id }
rel_person_location { person_id, location_id, role_id }
rel_artifact_location { artifact_id, location_id, role_id }

我的目标是从包含所有人员、工件和位置的所有三个表中创建一个结果集。

为了解决这个问题,我尝试了以下语句:

select
  *
from
  person per
  full outer join rel_person_artifact rpa on per.person_id = rpa.person_id
  full outer join artifact art on art.artifact_id = rpa.artifact_id
  full outer join rel_artifact_location ral on ral.artifact_id = art.artifact_id
  full outer join location loc on loc.location_id = ral.location_id
  full outer join rel_person_location rpl on rpl.person_id = per.person_id;

此查询在语法上是正确的,但返回磨损的内容,因为连接处理一个接一个的表。归根结底,并不是每个关系都在结果集中表示。

有没有什么方法可以组合上表以获得完整正确的结果集?

编辑。以下是一些示例记录(我坚持交叉表):

rel_person_artifact ( 'Peter', 'car 1', 'owner' ), ( 'Alex', 'car 1', 'driver' )
rel_person_location ( 'Peter', 'location 1', 'home' ), ( 'Paul', 'location 2', 'place of work' )
rel_artifact_location ( 'car 1', 'location 1', 'parking' )

当然,数据可能比这个例子复杂得多。正如下面评论中提到的,也可能存在循环关系。

我不确定结果集应该是什么样子,我什至不确定这种组合是否可行?

非常感谢!

问候

4

1 回答 1

0

LEFT JOIN我终于通过使用和的组合解决了这个问题UNION。您可以解散属于某个观点的关系。这意味着您首先通过构建所需的视角LEFT JOIN,然后通过UNION.

所以,给定的例子可以解决如下:

-- person perspective
select
  per.person_id person_id,
  art.artifact_id artifact_id,
  loc.location_id location_id,
  rpa.role_id person_artifact_role_id,
  rpl.role_id person_location_role_id,
  null artifact_location_role_id -- This attribute cannot be filled in this perspective, so it has to be null to fit the common structure of both perspectives.
from 
  person per
  left join rel_person_artifact rpa on rpa.person_id = per.person_id
  left join artifact art on art.artifact_id = rpa.artifact_id
  left join rel_person_location rpl on rpl.person_id = per.person_id
  left join location loc on loc.location_id = rpl.location_id

union

-- location perspective
select
  per.person_id person_id,
  art.artifact_id artifact_id,
  loc.location_id location_id,
  null person_artifact_role_id, -- see above
  rpl.role_id person_location_role_id,
  ral.role_id artifact_location_role_id
from
  location loc
  left join rel_artifact_location ral on ral.location_id = loc.location_id
  left join artifact art on art.artifact_id = ral.artifact_id
  left join rel_person_location rpl on rpl.location_id = loc.location_id
  left join person per on per.person_id = rpl.person_id

-- ...

与 a UNIONas 连接的每个透视图都适合一个通用结构,因此在添加新透视图时必须调整每个透视图。

感谢您的回复,希望对遇到类似问题的人有所帮助。

于 2014-11-07T12:51:04.060 回答