我知道这个问题已经被问及并回答了。我理解这个问题,我理解其根本原因,我理解解决方案。我不明白的是如何实施解决方案。
我会尝试详细....
背景:每种材料都在WellID
(我在石油和天然气工作)和SandType
分组,这是我在每张桌子中的主键,这些来自2每个查找表一个。 (我在石油和天然气工作)
我有3张表,用于在作业过程中的3个不同阶段存储材料(沙子)重量。基本上是工程师设计的重量,交付的内容和库存中的内容。
我知道连接搞砸了,并为每个表中的每一行添加了总数。有时双倍三等。
我正在WellID
和SandID
进行分组。
现在我不想让别人为我做这项工作。我只是不知道如何或在何处访问将其限制为我想要的,或者如果修改sql是正确的编写代码的方法。当前的解决方法是为每个表分别进行3次单独的求和查询,但这会导致效率低下并添加步骤。
我的整个数据库目的和随后的报告取决于这三个数字的数学因此,我的节目限制在这里把肥胖的女士放在舞台上,并且即将成为行尾的交易破坏者! 0
我需要一些建议,方向,批评,智慧,诙谐的委婉或新工作!
3个表格如下
Design: T_DESIGN DesignID WellID Sand_ID Weight_DES Time_DES 89 201 1 100 4/21/2014 6:46:02 AM 98 201 2 100 4/21/2014 7:01:22 AM 86 201 4 100 4/21/2014 6:28:01 AM 93 228 5 100 4/21/2014 6:53:34 AM 91 228 1 100 4/21/2014 6:51:23 AM 92 228 1 100 4/21/2014 6:53:30 AM Delivered: T_BOL BOLID WellID_BOL SandID_BOL Weight_BOL 279 201 1 100 280 201 1 100 281 228 2 5 282 228 1 10 283 228 9 100 Inventory: T_BIN StrapID WellID_BIN SandID_BIN Weight_BIN 11 201 1 100 13 228 1 10 14 228 1 0 17 228 1 103 19 201 1 50
查询结果:
Test Query99 WellID WellID SandID Sum Of Weight_DES Sum Of Weight_BOL Sum Of Weight_BIN 201 1 400 400 300 228 1 600 60 226
SQL:
SELECT DISTINCTROW L_WELL.WellID, L_SAND.SandID,
Sum(T_DESIGN.Weight_DES) AS [Sum Of Weight_DES],
Sum(T_BOL.Weight_BOL) AS [Sum Of Weight_BOL],
Sum(T_BIN.Weight_BIN) AS [Sum Of Weight_BIN]
FROM ((L_SAND INNER JOIN
(L_WELL INNER JOIN T_DESIGN ON L_WELL.[WellID] = T_DESIGN.[WellID_DES])
ON L_SAND.SandID = T_DESIGN.[SandID_DES])
INNER JOIN T_BIN
ON (L_WELL.WellID = T_BIN.WellID_BIN)
AND (L_SAND.SandID = T_BIN.SandID_BIN))
INNER JOIN T_BOL
ON (L_WELL.WellID = T_BOL.WellID_BOL) AND (L_SAND.SandID = T_BOL.SandID_BOL)
GROUP BY L_WELL.WellID, L_SAND.SandID;
两个LooUp表用于Well Names和Sand Types。 (好的是缩写做大小)
L_Well:
WellID WellName_WELL
3 AAGVIK 1-35H
4 AARON 1-22
5 ACHILLES 5301 41-12B
6 ACKLINS 6092 12-18H
7 ADDY 5992 43-21 #1H
8 AERABELLE 5502 43-7T
9 AGNES 1-13H
10 AL 5493 44-23B
11 ALDER 6092 43-8H
12 AMELIA FEDERAL 5201 41-11B
13 AMERADA STATE 1-16X
14 ANDERSMADSON 5201 41-13H
15 ANDERSON 1-13H
16 ANDERSON 7-18H
17 ANDRE 5501 13-4H
18 ANDRE 5501 14-5 3B
19 ANDRE SHEPHERD 5501 14-7 1T
Sand Lookup:
LSand
SandID SandType_Sand
1 100 Mesh
2 20/40 EP
3 20/40 RC
4 20/40 W
5 30/50 Ceramic
6 30/50 EP
7 30/50 RC
8 40/70 EP
9 40/70 W
10 NA See Notes
答案 0 :(得分:3)
我注意到你对如何实现聚合查询背后的一些理论的指点的关注。虽然SQL查询是解决困难分析问题核心的良好电源工具,但展示如何使用MS Access的内置设计工具将各种事物组合在一起可能也很有用。
此解决方案是在MS Access 2010上开发的。
以前解决方案的评论
@xQbert在以下SQL语句中有一个坚实的开端。可以将子查询方法可视化为在Access中创建的单个查询对象:
FROM
(SELECT WellID, Sand_ID, Sum(weight_DES) as sumWeightDES
FROM T_DESGN) A
INNER JOIN
(SELECT WellID_BOL, Sum(Weight_BOL) as SUMWEIGHTBOL
FROM T_BOL B) B
ON A.Well_ID = B.WellID_BOL
INNER JOIN
(SELECT WellID_BIN, sum(Weight_Bin) as SumWeightBin
FROM T_BIN) C
ON C.Well_ID_BIN = B.Well_ID_BOL
根据业务数据的实际规则,在此查询中做出的以下假设可能不一定如此:
T_DESIGN
,T_BOL
和T_BIN
的表格会同时填充吗?样本数据具有混合值,即,WellID
和SandID
组合不具有所有这三个类别的值。
INNER
类型连接假设所有三个表都有每个维度值的记录(Well-Sand组合) @Frazz通过建议选择" base"来改进查询设计。加入表格(在这种情况下为T_DESIGN
),此表格必须填充所有相关的维度值(WellID
和SandID
组合)。
SELECT
WellID_DES AS WellID,
SandID_DES AS SandID,
SUM(Weight_DES) AS Weight_DES,
(SELECT SUM(Weight_BOL) FROM T_BOL WHERE T_BOL.WellID_BOL=d.WellID_DES
AND T_BOL.SandID_BOL=d.SandID_DES) AS Weight_BOL,
(SELECT SUM(Weight_BIN) FROM T_BIN WHERE T_BIN.WellID_BIN=d.WellID_DES
AND T_BIN.SandID_BIN=d.SandID_DES) AS Weight_BIN
FROM T_DESIGN;
(... note: a group-by statement should be here...)
这是一个改进,因为现在所有的连接都来自一个点。如果T_BOL
或T_BIN
中不存在键值,结果仍会返回,并且查询的整个记录不会丢失。
同样,可能没有T_DESIGN
条记录与其他表中存储的值匹配。
所呈现的数据并未表明三个表格中每个表格中的数据之间存在任何直接交互,除了基于公共键值对(WellID
和SandID
)。由于我们使用的是Access,因此可以单独进行这些计算。
此查询是使用"总结"设计的。 Access查询设计工具的功能。在指向T_DESIGN
表之后,它的输出如下所示:
关于cartesian products的意见不一,但实际上它们确实有目的。
大多数问题是失控的笛卡尔积产品查询将产生数以百万计的无意义数据值。在此查询中,它专门用于模拟真实的业务条件。
笛卡尔积的案例
从提供的样本数据中挑选:
参考尺寸查询产品
维度查询很容易生成。通过引用两个密钥源:L_WELL
和L_SAND
(都查找表或维表)而不识别连接条件,两个键值(WellID和SandID)的所有不同组合都是制成:
SQL中的快捷方式如下所示:
SELECT L_WELL.WellID, L_SAND.SandID, L_WELL.WellName, L_SAND.SandType
FROM L_SAND, L_WELL;
结果数据如下所示:
而不是使用任何运营数据表:T_DESIGN
,T_BOL
或T_BIN
作为静态维度的数据来源,例如油井列表或目录沙子类型,数据已经预先确定,甚至可以转移到真实的表格,因为它一旦创建就不会有太大变化。
重复该过程并为其他两个来源(T_BOL
和T_BIN
)创建摘要表后,您最终可以通过简单的查询和加入流程来安排结果。
实际的JOIN操作位于维度表/查询:QSUB_WELL_SAND
和所有三个摘要查询之间:QSUB_DES
,QSUB_BOL
和QSUB_BIN
。
我选择实施LEFT OUTER
加入。如果你不确定不同的"外部"加入,这是我通过Access Query Design对话框做出的选择:
QSUB_WELL_SAND
被定义为我们的锚点维度。它将始终拥有比任何其他表更多的记录。应定义OUTER JOIN
以保留所有引用维度记录...以及所有摘要表查询结果,无论两个查询结果之间是否匹配。
QSUB_WEIGHTS /结合所有子查询结果的查询
这是最终输出查询的设计:
这是执行此查询设计时数据输出的样子:
对于维度查询的连接,存在大量空白空间,其中没有要报告的记录或数据。这是一个巧妙放置的过滤器或查询条件可以将输出缩小到您最关注的位置。在我添加其他结束查询条件后,我的处理方式如下:
我的数据基于OP提供的内容,除非分配给Well Type
属性的ID与样本数据不匹配。我指定的值也会在下面发布。
Access支持不同风格的数据库操作。可以开发逐步查询来保存预处理的特殊数据集,这些数据可以重新引入其他数据表并查询结果以开发复杂的查询标准。
所有这一切, SQL编程也同样有益。 一定要探索结果和可以利用的功能之间的一些差异通过使用一种方法(sql编码),另一种方法(访问设计向导)或两种方法。通过这里提供的示例,确实有很大的发展空间和发现新功能。
希望我没有从为您的情况开发解决方案中窃取所有乐趣。我读到了你关于"建立更多"作为更有趣的预兆,所以我感觉不是很糟糕......!快乐发展!
样本集中的数据修改
答案 1 :(得分:1)
我会简化它,不包括L_WELL和L_SAND。如果你只是想要ID,那么它们真的不应该是必要的连接。如果所有其他3个表都有WellID和SandID列,那么选择一个肯定有所有组合的列。
假设它是Design表,那么:
SELECT
WellID_DES AS WellID,
SandID_DES AS SandID,
SUM(Weight_DES) AS Weight_DES,
(SELECT SUM(Weight_BOL) FROM T_BOL WHERE T_BOL.WellID_BOL=d.WellID_DES AND T_BOL.SandID_BOL=d.SandID_DES) AS Weight_BOL,
(SELECT SUM(Weight_BIN) FROM T_BIN WHERE T_BIN.WellID_BIN=d.WellID_DES AND T_BIN.SandID_BIN=d.SandID_DES) AS Weight_BIN
FROM T_DESIGN
GROUP BY WellID, SandID;
...并确保所有表都有WellID和SandID的索引。
要清楚。我认为从查找表或笛卡尔积中开始连接是个好主意。您始终可以将它们连接起来以获取描述和其他数据。但是主要查询应该是具有WellID和SandID的所有组合的那个...或者如果不是全部,则至少是最多的。如果3个表(DESIGN,BOL和BIN)中没有一个具有所有组合,则事情变得困难。在那种情况下(我只说在那种情况下),那么你也可以从两个查找表的笛卡尔积开始。你也可以做一个UNION,但我怀疑那会更有效率。
答案 2 :(得分:1)
如果不了解L_SAND和L_WELL,这是我能想到的最好的...... 使用sub选项首先获得总和,这样就不会在连接上复合数据问题。
Select WellID, Sand_ID, sumWeightDES, WellID_BOL, SUMWEIGHTBOL,
WellID_BIN, SumWeightBin
FROM
(SELECT WellID, Sand_ID, Sum(weight_DES) as sumWeightDES
FROM T_DESGN) A
INNER JOIN
(SELECT WellID_BOL, Sum(Weight_BOL) as SUMWEIGHTBOL
FROM T_BOL B) B
ON A.Well_ID = B.WellID_BOL
INNER JOIN
(SELECT WellID_BIN, sum(Weight_Bin) as SumWeightBin
FROM T_BIN) C
ON C.Well_ID_BIN = B.Well_ID_BOL