SQL查询自";三角关系;桌子

SQL查询自";三角关系;桌子,sql,ms-access,Sql,Ms Access,我很难在SQL中找到一个看似简单的正确答案。我正在使用MS Access,但我想在这里这并不重要。 我的数据结构如下所示: qryProdModComp = SELECT tblA.Product, mapBC.Component, mapAC.Module FROM (tblA LEFT JOIN mapAC ON tblA.Product = mapAC.Product) LEFT JOIN mapBC ON mapAC.Module = mapBC.Module; 因此tblA有“产品

我很难在SQL中找到一个看似简单的正确答案。我正在使用MS Access,但我想在这里这并不重要。 我的数据结构如下所示:

qryProdModComp = SELECT tblA.Product, mapBC.Component, mapAC.Module
FROM (tblA LEFT JOIN mapAC ON tblA.Product = mapAC.Product) LEFT JOIN mapBC ON mapAC.Module = mapBC.Module;

因此
tblA
有“产品”、
tblB
有“组件”和
tblC
有“模块”。显然,这只是一个例子。
tblA
(“产品”)与
tblB
(“组件”)有m:n关系,即一个产品由一些组件组成,组件可以属于许多产品
tblB
(“组件”)与
tblC
(“模块”)有m:n关系,即组件由模块组成,模块可以属于许多组件。现在的转折点是,我在
tblA
tblC
之间也有一个m:n关系,即产品和模块的映射。这是因为组件的“配置”可能因其所针对的产品而异。因此,对于“产品1”,组件2需要包括“模块1”和“模块2”,而对于“产品2”,组件2只是“模块2”

我想要一个结果如下的查询

|Product|Component|Module|
|-------|---------|------|
|Prod1  |C1       |      |
|Prod1  |C2       |      |
|Prod1  |C2       |M1    |
|Prod1  |C2       |M2    |
|Prod2  |C2       |      |
|Prod2  |C2       |M2    |
|Prod2  |C3       |      |
|Prod2  |C3       |M3    |
其中,tblA中有“Prod1”和“Prod2”;
tblB
中的“C1”、“C2”、“C3”和
tblC
中的“M1”、“M2”、“M3”。关系是

所以本质上我想要一个包含产品、组件和模块的表,其中包含所有产品组合+

现在使用SQL查询

SELECT tblA.Product,
       tblB.Component,
       tblC.Module
FROM tblC
INNER JOIN ((tblA
             INNER JOIN (tblB
                         INNER JOIN mapAB ON tblB.[Component] = mapAB.[Component]) ON tblA.[Product] = mapAB.[Product])
            INNER JOIN mapAC ON tblA.Product = mapAC.Product) ON tblC.Module = mapAC.Module;
我明白了

这是可以理解的,但不是我想要的。我已尝试先执行
tblA
tblB
的联接,并将其与左联接(或右联接)和
tblB
tblC
的联接相结合,但这会产生“不支持的联接操作”错误


关于如何解决这个问题,您有什么想法吗?

看看您的关系,您没有使用主键来建立一对多关系,而是使用数据字段

在这种情况下,此查询应适用于您:

SELECT tblA.Product, mapAC.Module, MapAB.Component
FROM (tblA LEFT JOIN mapAC ON tblA.Product = mapAC.Product) LEFT JOIN MapAB ON tblA.Product = MapAB.Product;
在本例中,所有其他表格都只是提供信息,因为您已经在表格
MapAB
MapAC
中获得了可用的数据

我建议在你的关系中使用主键

更新: 您的查询可以通过三种途径获得所需的数据:

  • tblA->mapAB+mapAC
  • tblA->mapAB->tblB->mapBC->tblC
  • tblA->mapAC->tblC->mapBC->tblB
  • 根据要遵循的数据路径,查询的外观会有所不同

    路线2查询:

    SELECT tblA.Product, MapAB.Component, mapBC.Module
    FROM (((tblA LEFT JOIN MapAB ON tblA.Product = MapAB.Product) LEFT JOIN tblB ON MapAB.Component = tblB.Component) LEFT JOIN mapBC ON tblB.Component = mapBC.Component) LEFT JOIN tblC ON mapBC.Module = tblC.Module;
    
    路线3查询:

    SELECT tblA.Product, mapAC.Module, mapBC.Component
    FROM (((tblA LEFT JOIN mapAC ON tblA.Product = mapAC.Product) LEFT JOIN tblC ON mapAC.Module = tblC.Module) LEFT JOIN mapBC ON tblC.Module = mapBC.Module) LEFT JOIN tblB ON mapBC.Component = tblB.Component;
    

    好的,根据jbud的建议,我能够建立如下所示的预期结果:

    qryProdModComp = SELECT tblA.Product, mapBC.Component, mapAC.Module
    FROM (tblA LEFT JOIN mapAC ON tblA.Product = mapAC.Product) LEFT JOIN mapBC ON mapAC.Module = mapBC.Module;
    
    几乎已经给了我想要的

    但是请注意,缺少带有Prod1和C1的行(没有直接链接Mx)。 为了得到这个,我加了一句

    qrySingleC = SELECT tblB.Component AS Component
    FROM   tblB
           LEFT JOIN mapBC
           ON tblB.Component = mapBC.Component
    WHERE  mapBC.Component Is Null
    UNION
    SELECT mapBC.Component
    FROM   tblB
           RIGHT JOIN mapBC
           ON tblB.Component = mapBC.Component
    WHERE  tblB.Component Is Null
    
    qryProdCompOnly = SELECT tblA.Product, mapAB.Component, NULL AS Module
    FROM tblA INNER JOIN ( qrySingleC INNER JOIN mapAB ON qrySingleC.Component = mapAB.Component  ) ON tblA.Product = mapAB.Product;
    
    qryOverall = SELECT Product,Component,Module FROM qryProdCompMod UNION SELECT Product,Component,Module FROM qryProdCompOnly;
    

    得到与我在原始帖子中要求的完全相同的结果,实际上看起来还是有点干净

    qryProdCompOnly2 = SELECT tblA.Product, mapAB.Component, NULL AS Module
    FROM tblA INNER JOIN mapAB ON tblA.Product = mapAB.Product;
    
    qryOverall = SELECT Product,Component,Module FROM qryProdCompMod UNION SELECT Product,Component,Module FROM qryProdCompOnly2;
    
    给予


    谢谢你的建议。我认为这是正确的方向。但它还没有给出我想要的结果。您的查询将生成组件(tblB)和模块(tblC)的所有组合,而不仅仅是mapAC允许的组合。可能是因为第一个左连接或多或少忽略了mapAC?在最关键的事情上,你是对的。这主要是为了说明。请分享您想要遵循的数据路径,请参阅更新的答案。我提供的查询,遵循路径1从第一眼看到它。路径2将是我想要的路径。我试着这样做(tblaA LEFT(tblAB LEFT tblB))LEFT(mapBC LEFT tblC)。但是,要么我的语法错误,要么这不是下一个连接操作的正确方法,我还没有让它工作。看看您的数据/结构和所需的结果,我认为您无法使用此结构实现结果使用
    tblA、tblB、tblC和mapABC
    简化您的结构不是更容易吗?这样,您就可以控制产品、组件和模块组合。mapABC将包含结果中所需的字段,因此不需要复杂的/计算过的查询。是的,我想这会更容易,我目前正在考虑这样做。这将对我的数据模型的其他部分产生影响,我仍然需要权衡这方面的努力与这一主题获得的简单性。。。无论如何,我只是想分享这个方法,因为它回答了我最初的问题。非常感谢你的帮助!