SQL查询自";三角关系;桌子
我很难在SQL中找到一个看似简单的正确答案。我正在使用MS Access,但我想在这里这并不重要。 我的数据结构如下所示: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有“产品
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
中获得了可用的数据
我建议在你的关系中使用主键
更新:
您的查询可以通过三种途径获得所需的数据:
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将包含结果中所需的字段,因此不需要复杂的/计算过的查询。是的,我想这会更容易,我目前正在考虑这样做。这将对我的数据模型的其他部分产生影响,我仍然需要权衡这方面的努力与这一主题获得的简单性。。。无论如何,我只是想分享这个方法,因为它回答了我最初的问题。非常感谢你的帮助!