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
我一直在修补 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