问题描述
我正在构建一个 ms access 数据库来管理混合物的零件编号。这几乎是一份材料清单。我有一个表 tblMixtures
在 PreMixture
字段中引用自身。我这样设置,这样一个混合物可以是另一种混合物中的预混物,而后者又可以是另一种混合物中的预混物,等等。PartNumber
中的每个 tblMixture
都与许多 { Component
在 tblMixtureComponents
中的 {1}}。 PartNumber
及其关联数据存储在 Component
中。我在下表中输入了示例数据。
tbl混合物
零件编号 | 说明 | 预混料 |
---|---|---|
1 | 混合物 1 | 4、5 |
2 | 混合物 2 | 4、6 |
3 | 混合物 3 | |
4 | 混合物 4 | 3 |
5 | 混合物 5 | |
6 | 混合物 6 |
tblMixtureComponents
ID | 零件编号 | 组件 | 专注 |
---|---|---|---|
1 | 1 | A | 20% |
2 | 1 | B | 40% |
3 | 1 | C | 40% |
4 | 2 | A | 40% |
5 | 2 | B | 30% |
6 | 2 | D | 30% |
tblComponentData
ID | 姓名 | 密度 | 类别 |
---|---|---|---|
1 | A | 1.5 | O |
2 | B | 2 | F |
3 | C | 2.5 | 我 |
4 | D | 1 | F |
我已经构建了将最终混合物的信息汇总在一起所需的查询,甚至显示了用于每个混合物的预混合物和成分的详细信息。然而,实际上有数以万计的零件编号,用于混合物的预混料可能会有很多重叠。换句话说,tblComponentData
可以用作 Mixture 4
和 Mixture 1
的预混物等等。我想构建一个查询来识别所有可能的混合物,这些混合物可以用作选定混合物中的预混物。所以我想要一个所有混合物的列表,这些混合物具有与所选混合物相同的组件或组件子集。预混料不必包含混合物中的所有成分,但不能包含任何不在混合物中的成分。
解决方法
如果你还没有解决它...
存储数据集合的 PreMixtures 列表明您需要更多地“规范化”您的数据库设计。如果您要从查询中获取预混数据,则无需将其存储为表数据。如果这样做,则每次您的混合物或组分发生变化时,您都将被迫更新预混数据。
我们还需要说明 tblMixtures 没有 id 字段。考虑以下表格更改:
tbl混合物:
id | 描述 |
---|---|
1 | 混合物 1 |
2 | 混合物 2 |
3 | 混合物 3 |
tblMixtureComponent:
id | mixtureId | componentId |
---|---|---|
1 | 1 | A |
2 | 1 | B |
3 | 1 | C |
4 | 2 | A |
5 | 2 | B |
6 | 2 | D |
7 | 3 | A |
8 | 4 | B |
我个人喜欢使用暴露主键和外键关系的列命名。 tblMixtures.id 显然与 tblMixtureComponenets.mixtureId 相关。我很懒,所以我也可能会缩写所有内容。
现在就查询而言,首先让我们获取混合物 1 的成分:
SELECT tblMixtureComponent.mixtureId,tblMixtureComponent.componentId
FROM tblMixtureComponent
WHERE tblMixtureComponent.mixtureId = 1
应该返回:
mixtureId | componentId |
---|---|
1 | A |
1 | B |
1 | C |
我们可以将 WHERE 子句更改为我们想要的任何混合物的 id。接下来,我们需要获取所有带有坏组件的混合 ID。所以我们将建立一个连接来比较最后一个查询:
SELECT tblMixtureComponent.mixtureId
FROM tblMixtureComponenet LEFT JOIN
(SELECT tblMixtureComponent.mixtureId,tblMixtureComponent.componentId
FROM tblMixtureComponent
WHERE tblMixtureComponent.mixtureId = 1) AS GoodComp
ON tblMixtures.componentId = GoodComp.componentId
WHERE GoodComp.componentId Is Null
应该返回:
mixtureId |
---|
2 |
太好了,现在我们有了我们不想要的所有混合物的 ID。让我们添加另一个连接以获得相反的结果:
SELECT tblMixture.id
FROM tblMix LEFT JOIN
(SELECT tblMixtureComponent.mixtureId
FROM tblMixtureComponenet LEFT JOIN
(SELECT tblMixtureComponent.mixtureId,tblMixtureComponent.componentId
FROM tblMixtureComponent
WHERE tblMixtureComponent.mixtureId = 1) AS GoodComp
ON tblMixtures.componentId = GoodComp.componentId
WHERE GoodComp.componentId Is Null) AS BadMix
ON tblMixtures.id = BadMix.mixtureId
WHERE BadMix.mixtureId = Null AND tblMixture.id <> 1
应该返回:
mixtureId |
---|
3 |
4 |
剩下的是与混合物 1 具有相似成分但不具有非相似成分的所有 id。
抱歉,我是在手机上做的...