SQL引用同一个表两次

时间:2015-04-24 03:13:57

标签: mysql database foreign-keys primary-key

我一直在修改SQL来为业务开发数据库,​​我有一个表,它通过主键引用另一个表,但出于不同的原因这样做了两次。我可以这样做,更重要的是我应该这样做吗?

因此,假设我们为其他公司修理汽车,我们有一个我们工作的每辆车的数据库。我们为一家名为Lots-o-Rental Cars的公司修理汽车,另一家名为Cool Cars。

现在虽然酷车有自己选择的汽车,但他们还与Lots-o-Rental汽车达成协议,借用一些汽车。有些情况下,我们会为我们在汽车上的工作向Lots-o-Rental汽车收取费用,但有时我们会向Cool Cars收取在同一辆汽车上完成的工作。

我目前的设置(在此简化)看起来有点像这样:

表:公司

列: company_id(pk),company_name

1,Lot-so-Rental Cars

2,酷车

分支(用于显示同一公司的多个营业地点)

列: branch_id(pk),company_id(fk)

1,1

2,1

3,2

表:汽车

列: car_id(pk),car_brand,car_model,owner_id(fk),on_hire,hiree_id(fk)

'owner_id'和'hiree_id'都是分支表中的branch_id。 'on_hire'是一个值,用于确定汽车当前是否被雇用给我们服务的另一家公司时判定为真还是假。

1,福特,野马,1,是,3

2,VW,Beetle,1,NO,NULL

3,Nissan,Pulsar,2,NO,NULL

4,雪佛兰,Camaro,3,NO,NULL

使用此布局,我可以选择car_brand,car_model,owner_id(显示为company_name),如果租车也显示hiree_id(显示为company_name)?

2 个答案:

答案 0 :(得分:3)

是的,你可以这样做。在同一个表格中有两个不同的外键列( owner_id hiree_id )是完全有效的( car )引用相同的表格( company )。

只要每个外键的“域”相同,就可以这样做。 (“域”是列的允许值集。)遇到麻烦的地方是你想要允许的地方(作为一个例子)“酷车”是“hiree”但不允许它是“所有者”。然后,数据库强制执行这种约束是非常重要的。只要 company 中的每一行都可以成为“hiree”和“所有者”的有效参考,那么就可以了。

<强>后续

问:我将使用什么SQL语句来显示car_brand,car_model,company_name AS“拥有者”和company_name AS“雇佣者”?

A:您的SELECT语句需要对company表进行两次引用。

由于对查询中对company表的两个引用中的列的引用将不明确,我们必须限定列引用,并且至少有一个引用公司表将要求我们指定别名以消除参考的歧义。 (这是一个示例,说明了我们的模式始终为查询中的表引用分配别名,并限定所有列引用。)

SELECT c.car_brand
     , c.car_model
     , o.company_name AS `Owned by`
     , h.company_name AS `Hired by`
  FROM `cars` c
  LEFT
  JOIN `company` o
    ON o.company_id = c.owner_id
  LEFT
  JOIN `company` h
    ON o.company_id = c.hiree_id
 ORDER BY c.car_brand, c.car_model, o.company_name, h.company_name

<强>后续

道歉。我完全错过了branch表。该查询也需要引用该表。

SELECT c.car_brand
     , c.car_model
     , o.company_name AS `Owned By`
     , h.company_name AS `Hired by` 
  FROM cars c
  LEFT
  JOIN branch bo
    ON c.owner_id = bo.branch_id
  LEFT
  JOIN company o
    ON bo.company_id = o.company_id 
  LEFT
  JOIN branch bh
    ON c.hiree_id = bh.branch_id
  LEFT
  JOIN company h 
    ON bh.company_id = h.company_id
 ORDER
    BY c.car_brand
     , c.car_model
     , o.company_name
     , h.company_name

答案 1 :(得分:0)

对于这种情况,两次引用主键对我来说似乎很好。一种可能的替代方法是摆脱on_hire,因为hiree_id == NULL基本上不是on_hire。你应该可以获得你想要的信息。