1-й вопрос:
SELECT
distinct t.TaskID
FROM
Floor f
inner join
Area a
on
f.FloorID = a.FloorID
left join
Asset ast
on
a.AreaID = ast.AreaID
inner join
Task t
on
t.AreaID = a.AreaID or
t.AssetID = ast.AssetID
WHERE
f.FloorID = @FloorID
должно дать вам форму запроса, который вы пытаетесь построить. (Конечно, вам на самом деле не нужно запрашивать таблицу Floor, если у вас уже есть FloorID)
2-й вопрос:
CREATE TABLE Task (
TaskID int not null,
AreaID int null,
AssetID int null,
constraint PK_Task PRIMARY KEY (TaskID),
constraint FK_Task_Area FOREIGN KEY (AreaID) references Area (AreaID),
constraint FK_Task_Asset FOREIGN KEY (AssetID) references Asset (AssetID),
constraint CK_Task_OneNonNull CHECK (
(AreaID is null and AssetID is not null) or
(AssetID is null and AreaID is not null))
)
Или, в качестве альтернативы, вы можете сделать AreaID не равным NULL, добавить уникальное ограничение для таблицы активов (AreaID, AssetID), а затем сделать внешний ключ для таблицы активов ссылкой на оба столбца - это гарантирует, что если AssetID предоставляется, это ссылка на актив, который принадлежит правильному AreaID. Это также упростит ответ на вопрос Q1, если в Task
всегда есть AreaID
3-ий вопрос:
Трудно сказать, не зная, как все это будет использоваться. Я не думаю, что это un -разумный подход.