Что такое структура данных SQL Server для представления нескольких объектов, соединенных вместе? - PullRequest
0 голосов
/ 25 июня 2018

Предположим, у меня есть две таблицы в базе данных SQL Server: dbo.Companies и dbo.Contracts.

Предположим, что я хочу представлять отношения один-к-одному между компаниями и контрактами, чтобы указать, что контракт был заключен с компанией.Я бы просто создал таблицу соединения с внешним ключом для dbo.Companies и dbo.Contracts.

. Вышеуказанный сценарий прост для любого опытного разработчика SQL.

Предположим, что я хочусделать что-то подобное, но каждая компания, которой присужден контракт, может заключить субконтракт с другой компанией, которая может заключить субконтракт дальше.

У меня может быть компания под названием «Acme», которая может заключить субконтракт с «Злыми гениями», что может привести к субконтракту «Зло в бюджете».

Или, опять же, «Акме» может заключить субконтракт с «Злыми гениями», который субконтрактует к «Злу в бюджете», но «Акме» может одновременно заключить субконтракт с другимчасть одного и того же контракта с «Падающими наковальнями».

Следует иметь в виду, что компания может быть вовлечена во множество различных контрактов на разных уровнях или в системе могут быть компании, которым не присужденоконтракты вообще.

Какая структура данных позволяет мне описывать эти отношения в SQL?

Edit: Я использую MS SQL Server.

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Достаточно того же, что и отношение один-к-одному (или один-ко-многим).

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;

Я полагаю, вы используете Microsoft SQL Server на основе использования dbo. Чтение Рекурсивные запросы с использованием общих табличных выражений для получения дополнительной информации.

0 голосов
/ 25 июня 2018

Я бы использовал таблицу contracts, например:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...