我一直在修改 SQL 来为企业开发数据库,我有一个表,它通过主键引用另一个表,但出于不同的原因这样做了两次。我可以这样做吗?更重要的是,我应该这样做吗?
假设我们为其他公司修理汽车,并且我们拥有我们维修过的每辆汽车的数据库。我们为一家名为 Lots-o-Rental Cars 的公司和另一家名为 Cool Cars 的公司修理汽车。
现在,虽然 Cool Cars 可以选择自己的汽车,但他们还与 Lots-o-Rental Cars 达成协议(protocol),可以借用他们的一些汽车。在某些情况下,我们会针对我们在汽车上所做的工作向 Lots-o-Rental Cars 收费,但有时我们会针对在同一辆车上所做的工作向 Cool Cars 收费。
我当前的设置(此处已简化)看起来有点像这样:
表:公司
列: company_id (pk), company_name
1、很多租车
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,尼桑, pulsar ,2,不,空
4, 雪佛兰, 科迈罗, 3, NO, NULL
使用此布局,我是否可以选择 car_brand、car_model、owner_id(显示为 company_name),如果汽车被租出去还显示 hiree_id(显示为 company_name)?
最佳答案
是的,你可以做到这一点。在同一个表 (car
) 引用同一个表(company
)。
只要每个外键的“域”相同,就可以这样做。 (“域”是该列的一组允许值。)您遇到麻烦的地方是您想要允许(例如)“Cool Cars”成为“受雇人”但不允许它成为“所有者”。然后,数据库强制执行这种约束并非易事。只要 company
中的每一行都可以是来自“雇员”和“所有者”的有效引用,就可以了。
跟进
问:我应该使用什么 SQL 语句来显示 car_brand、car_model、company_name AS "Owned by"和 company_name AS "Hired by"?
答:您的 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
关于mysql - SQL引用同一张表两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29838096/