什么是 SQL 服务器数据结构来表示链接在一起的几个对象?
What is a SQL Server data structure to represent several objects chained together?
假设我在 SQL 服务器数据库中有两个 table:dbo.Companies
和 dbo.Contracts
。
假设我想表示公司和合同之间的一对一关系,以表明合同已授予公司。我会简单地创建一个连接 table,外键指向 dbo.Companies
和 dbo.Contracts
.
上述场景对于任何有经验的 SQL 开发人员来说都很容易。
然后假设我想做类似的事情,但是每家获得合同的公司都可以分包给另一家公司,另一家公司可以进一步分包出去。
我可能有一家名为 "Acme" 的公司,它可能会转包给 "Evil Geniuses",它可能会转包给 "Evil on a Budget"。
或者,我 "Acme" 可能会转包给 "Evil Geniuses",后者会转包给“Evil on a Budget”,但 "Acme" 可能会同时将同一合同的另一部分转包给 "Falling Anvils".
必须记住,一家公司可能涉及许多不同级别的不同合同,或者系统中可能有公司根本没有获得任何合同。
哪种数据结构允许我在 SQL 中描述这些关系?
编辑:我正在使用 MS SQL 服务器。
我会使用 contracts
table 比如:
contract_id primary key,
company_id foreign key (companies.company_id),
parent_id foreign key (contracts.contract_id),
*** contract_level,
*** contract details
contract_level
这里是可选的,根据业务需求。此查询的最大缺点是无法在一次查询中找到合同的顶级所有者。这可以通过在顶级合约中添加一个像 contract_family
等于 contract_id 的列来解决。查看所有链的查询如下:
select * from contracts
left join companies on contracts.company_id = companies.company_id
where contract_family = ...
order by contract_level
同上一对一(或一对多)关系即可。
SQL 允许递归遍历这种关系。
我没有测试过以下查询,但它应该给你一个基本的想法。
WITH RECURSIVE ContractHolders AS (
SELECT * FROM dbo.Companies AS m
JOIN dbo.Contracts AS n ON m.id = n.ContractHolderId
WHERE m.name = 'Acme'
UNION ALL
SELECT m.* FROM ContractHolders AS h
JOIN dbo.Companies AS m ON m.id = h.ContractRecipientId
JOIN dbo.Contracts AS n ON m.id = n.ContractHolderId
)
SELECT * FROM ContractHolders;
根据您对 dbo.
的使用,我猜您使用的是 Microsoft SQL 服务器 阅读 Recursive Queries Using Common Table Expressions 了解更多信息。
假设我在 SQL 服务器数据库中有两个 table:dbo.Companies
和 dbo.Contracts
。
假设我想表示公司和合同之间的一对一关系,以表明合同已授予公司。我会简单地创建一个连接 table,外键指向 dbo.Companies
和 dbo.Contracts
.
上述场景对于任何有经验的 SQL 开发人员来说都很容易。
然后假设我想做类似的事情,但是每家获得合同的公司都可以分包给另一家公司,另一家公司可以进一步分包出去。
我可能有一家名为 "Acme" 的公司,它可能会转包给 "Evil Geniuses",它可能会转包给 "Evil on a Budget"。
或者,我 "Acme" 可能会转包给 "Evil Geniuses",后者会转包给“Evil on a Budget”,但 "Acme" 可能会同时将同一合同的另一部分转包给 "Falling Anvils".
必须记住,一家公司可能涉及许多不同级别的不同合同,或者系统中可能有公司根本没有获得任何合同。
哪种数据结构允许我在 SQL 中描述这些关系?
编辑:我正在使用 MS SQL 服务器。
我会使用 contracts
table 比如:
contract_id primary key,
company_id foreign key (companies.company_id),
parent_id foreign key (contracts.contract_id),
*** contract_level,
*** contract details
contract_level
这里是可选的,根据业务需求。此查询的最大缺点是无法在一次查询中找到合同的顶级所有者。这可以通过在顶级合约中添加一个像 contract_family
等于 contract_id 的列来解决。查看所有链的查询如下:
select * from contracts
left join companies on contracts.company_id = companies.company_id
where contract_family = ...
order by contract_level
同上一对一(或一对多)关系即可。
SQL 允许递归遍历这种关系。
我没有测试过以下查询,但它应该给你一个基本的想法。
WITH RECURSIVE ContractHolders AS (
SELECT * FROM dbo.Companies AS m
JOIN dbo.Contracts AS n ON m.id = n.ContractHolderId
WHERE m.name = 'Acme'
UNION ALL
SELECT m.* FROM ContractHolders AS h
JOIN dbo.Companies AS m ON m.id = h.ContractRecipientId
JOIN dbo.Contracts AS n ON m.id = n.ContractHolderId
)
SELECT * FROM ContractHolders;
根据您对 dbo.
的使用,我猜您使用的是 Microsoft SQL 服务器 阅读 Recursive Queries Using Common Table Expressions 了解更多信息。