SQL 引用相同的 table 两次

SQL referencing same table twice

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

假设我们为其他公司修理汽车,并且我们拥有我们维修过的每辆汽车的数据库。我们为一家名为 Lots-o-Rental Cars 的公司和另一家名为 Cool Cars 的公司修理汽车。

现在,虽然 Cool Cars 拥有 select 自己的汽车,但他们也与 Lots-o-Rental Cars 达成协议,可以借用他们的一些汽车。在某些情况下,我们会针对我们在汽车上所做的工作向 Lots-o-Rental Cars 收取费用,但有时我们会针对在同一辆车上完成的工作向 Cool Cars 收取费用。

我当前的设置(此处已简化)看起来有点像这样:

Table: 公司

列: company_id (pk),company_name

1,很多租车

2、酷车

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

列: branch_id (pk),company_id (fk)

1, 1

2, 1

3、2

Table:

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

'owner_id' 和 'hiree_id' 都是 branch_id 来自分支 table。 'on_hire' 是一个值,用于确定汽车目前是否租给了我们服务的另一家公司。

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

2,大众,甲壳虫,1,否,NULL

3,日产,Pulsar,2,否,NULL

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

使用这个布局,我可以selectcar_brand,car_model,owner_id(显示为company_name),如果租车还显示hiree_id(显示为company_name)?

我觉得在这种情况下两次引用主键似乎没问题。一种可能的替代方法是摆脱 on_hire,因为 hiree_id == NULL 基本上意味着不是 on_hire。而且您应该可以很好地获取所需的信息。

是的,你可以做到。在同一个 table (car) 引用相同的 table (company).

只要每个外键的 "domain" 相同就可以这样做。 ("domain" 是该列的一组允许值。)您 运行 遇到麻烦的地方是您希望允许(例如)"Cool Cars" 成为 "hiree" 但不允许它成为 "owner"。然后,数据库强制执行这种约束并非易事。只要 company 中的每一行都可以是 "hiree" 和 "owner" 的有效引用,那就没问题了。


跟进

Q: 我会用什么 SQL 语句来显示 car_brand, car_model, company_name AS "Owned by" 和 company_name AS "Hired by"?

A: 您的 SELECT 语句需要两次引用 company table.

并且由于在查询中对 company table 的两个引用对列的引用会产生歧义,我们必须 限定 列引用,并且至少有一个对公司 table 的引用需要我们指定一个 别名 来消除引用的歧义。 (这是一个示例,说明了我们的 always 为查询中的 table 引用分配别名并限定所有列引用的模式。)

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 table。该查询还需要引用该 table。

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