Access 2010在查询中加倍

时间:2014-04-22 19:27:15

标签: sql database join ms-access-2010

我知道这个问题已经被问及并回答了。我理解这个问题,我理解其根本原因,我理解解决方案。我不明白的是如何实施解决方案。

我会尝试详细....

背景:每种材料都在WellID(我在石油和天然气工作)和SandType分组,这是我在每张桌子中的主键,这些来自2每个查找表一个。 (我在石油和天然气工作)

我有3张表,用于在作业过程中的3个不同阶段存储材料(沙子)重量。基本上是工程师设计的重量,交付的内容和库存中的内容。

我知道连接搞砸了,并为每个表中的每一行添加了总数。有时双倍三等。

我正在WellIDSandID进行分组。

现在我不想让别人为我做这项工作。我只是不知道如何或在何处访问将其限制为我想要的,或者如果修改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

3 个答案:

答案 0 :(得分:3)

通过MS Access数据库查询和加入聚合数据

我注意到你对如何实现聚合查询背后的一些理论的指点的关注。虽然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_DESIGNT_BOLT_BIN的表格会同时填充吗?样本数据具有混合值,即,WellIDSandID组合不具有所有这三个类别的值。

Holes in Aggregated Weight Data

  • INNER类型连接假设所有三个表都有每个维度值的记录(Well-Sand组合)

@Frazz通过建议选择" base"来改进查询设计。加入表格(在这种情况下为T_DESIGN),此表格必须填充所有相关的维度值(WellIDSandID组合)。

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_BOLT_BIN中不存在键值,结果仍会返回,并且查询的整个记录​​不会丢失。

  • 同样,可能没有T_DESIGN条记录与其他表中存储的值匹配。

构建聚合子查询对象

所呈现的数据并未表明三个表格中每个表格中的数据之间存在任何直接交互,除了基于公共键值对(WellIDSandID)。由于我们使用的是Access,因此可以单独进行这些计算。

Design View of a Summarizing Query Pointed to T_DESIGN

此查询是使用"总结"设计的。 Access查询设计工具的功能。在指向T_DESIGN表之后,它的输出如下所示:

Summarized Query Results from T_DESIGN

通过笛卡尔积生成尺寸表

关于cartesian products的意见不一,但实际上它们确实有目的。

大多数问题是失控的笛卡尔积产品查询将产生数以百万计的无意义数据值。在此查询中,它专门用于模拟真实的业务条件。

笛卡尔积的案例

从提供的样本数据中挑选:

  • 部分沙型:" 20/40 EP"," 30/50陶瓷"," 40/70 EP&#34 ;和" 30/50 RC"在各自的井之间移动的是,这些井中的这些砂类型在全年都是一致的吗?

Sub Query for Weights Distributed by Well Name and Sand Type

  • 如果没有键值的锚定维度,则无法通过查询在数据库中的任何位置找到Wells。并不是说它们不存在......只是没有记录的数据(即交付的砂型重量)。

参考尺寸查询产品

维度查询很容易生成。通过引用两个密钥源:L_WELLL_SAND(都查找表或维表)而不识别连接条件,两个键值(WellID和SandID)的所有不同组合都是制成:

L_WELL and L_SAND Dimension Query Design

SQL中的快捷方式如下所示:

SELECT L_WELL.WellID, L_SAND.SandID, L_WELL.WellName, L_SAND.SandType
  FROM L_SAND, L_WELL;

结果数据如下所示:

WellID-SandID Dimension Query

而不是使用任何运营数据表:T_DESIGNT_BOLT_BIN作为静态维度的数据来源,例如油井列表或目录沙子类型,数据已经预先确定,甚至可以转移到真实的表格,因为它一旦创建就不会有太大变化。

关联来自不同来源的子查询结果

重复该过程并为其他两个来源(T_BOLT_BIN)创建摘要表后,您最终可以通过简单的查询和加入流程来安排结果。

实际的JOIN操作位于维度表/查询:QSUB_WELL_SAND和所有三个摘要查询之间:QSUB_DESQSUB_BOLQSUB_BIN

我选择实施LEFT OUTER加入。如果你不确定不同的"外部"加入,这是我通过Access Query Design对话框做出的选择:

Access Database Outer Join Definition

QSUB_WELL_SAND被定义为我们的锚点维度。它将始终拥有比任何其他表更多的记录。应定义OUTER JOIN以保留所有引用维度记录...以及所有摘要表查询结果,无论两个查询结果之间是否匹配。

QSUB_WEIGHTS /结合所有子查询结果的查询

这是最终输出查询的设计:

QSUB_WEIGHTS Query Design Panel View

这是执行此查询设计时数据输出的样子:

QSUB_WEIGHTS Query Results Data Output

结论和清理:一些结束的想法

对于维度查询的连接,存在大量空白空间,其中没有要报告的记录或数据。这是一个巧妙放置的过滤器或查询条件可以将输出缩小到您最关注的位置。在我添加其他结束查询条件后,我的处理方式如下:

QSUB_WEIGHTS Final Query Results and Sample Data Output

我的数据基于OP提供的内容,除非分配给Well Type属性的ID与样本数据不匹配。我指定的值也会在下面发布。

Access支持不同风格的数据库操作。可以开发逐步查询来保存预处理的特殊数据集,这些数据可以重新引入其他数据表并查询结果以开发复杂的查询标准。

所有这一切, SQL编程也同样有益。 一定要探索结果和可以利用的功能之间的一些差异通过使用一种方法(sql编码),另一种方法(访问设计向导)或两种方法。通过这里提供的示例,确实有很大的发展空间和发现新功能。

希望我没有从为您的情况开发解决方案中窃取所有乐趣。我读到了你关于"建立更多"作为更有趣的预兆,所以我感觉不是很糟糕......!快乐发展!

样本集中的数据修改

L_WELL Look Up Reference Table

答案 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