如何连接这些表以获得所有表的完整结果集?

How to join these tables for a full result set from all tables?

我有 table 个实体

我有 table B 件商品

我有 Table 个实体项及其关联的配置值。

我正在寻找一个视图,该视图将 return 我与实体 + 项目的每个组合排成一行,并使用来自 table C 的数据(如果存在)。

此外,如果 TableC 中有 TableB 中不存在的项目,我也想要那些

例如,

Table A 
Entity 1
Entity 2

Table B
Item X
Item Y
Item Z

Table C
Entity 1    Item X    True
Entity 1    Item Y    False
Entity 2    Item X    False
Entity 2    Item J    False


Result Table Wanted
Entity 1    Item X    True
Entity 1    Item Y    False
Entity 1    Item Z    Null
Entity 2    Item X    False
Entity 2    Item Y    Null
Entity 2    Item Z    Null
Entity 2    Item J    False

出于某种原因,我为此画了一个空白。自从我与 SQL 合作以来已经有一段时间了,所以也许我遗漏了一些明显的东西。有人可以帮助我确定编写此查询所需的语法吗?

我已经接近使用 CROSS JOIN

SELECT *
FROM Entities
CROSS JOIN Items
LEFT OUTER JOIN EntityItems 
    ON Entities.ID = EntityItems.EntityID
    AND Items.ID = EntityItems.ItemID

这 return 除了项目 J 的 Table C 中的行之外,我什么都知道。

更新:从头开始,它实际上 return 给我太多行了。这就是我现在正在玩的东西。

我正在使用 MS Sql Server 2017

你的cross join/left join是正确的做法:

SELECT e.EntityID, i.ItemId, COALESCE(ei.value, 'false') as value
FROM Entities e CROSS JOIN
     Items i LEFT JOIN
     EntityItems ei
    ON e.ID = ei.EntityID AND
       i.ID = ei.ItemID;

然而,这假定 ItemId 是正确定义的外键关系。您的 ItemId 似乎无效。您可以解决这个问题:

SELECT e.EntityID, i.ItemId, COALESCE(ei.value, 'false') as value
FROM Entities e CROSS JOIN
     (SELECT i.ItemId
      FROM Items i
      UNION  -- on purpose to remove duplicates
      SELECT ei.ItemId
      FROM EntityItems ei
     ) i LEFT JOIN
     EntityItems ei
    ON e.ID = ei.EntityID AND
       i.ID = ei.ItemID;

但是,我强烈建议您修复数据(即添加 J 到项目 table)并添加:

alter table entityitems add constraint fk_entityitems_entityid
    foreign key (entityid) references entities(entityid);

alter table entityitems add constraint fk_entityitems_itemid
    foreign key (itemid) references entities(itemid);

这将帮助您确保数据完整性(向前推进)- 在您修复数据之后。

编辑:

啊,您不希望所有实体都有额外的项目 ID。如果是:

SELECT e.EntityID, i.ItemId, COALESCE(ei.value, 'false') as value
FROM Entities e CROSS JOIN
     Items i LEFT JOIN
     EntityItems ei
    ON e.ID = ei.EntityID AND
       i.ID = ei.ItemID;
UNION ALL
SELECT ei.EntityId, ei.ItemId, ei.value
FROM EntityItems ei
WHERE NOT EXISTS (SELECT 1 FROM Items i WHERE i.ItemId = ei.ItemId);