【问题标题】:Summing multiple values into one table将多个值汇总到一个表中
【发布时间】:2016-06-15 12:09:15
【问题描述】:

我在 Microsoft Access 中有三个表:

  • 表 1 包括各个公司的名称和每个公司对应的唯一 ID(以及有关公司的其他唯一信息);
  • 表2包括各公司自2013年以来的销售信息;
  • 表 3 包括每个 2014 年的销售信息。

    在表 2 和表 3 中,通常不止一次列出一家公司,对应于不同州的销售额。

在表 2 和表 3 中,公司名称实际上是其对应的 ID 号,我使用查找来显示名称。因此,Table1 是 Table2 和 Table3 的父级。

我想创建一个查询,将每家公司以及表 2 和表 3 中的销售额总和仅列出一次。当我只尝试使用 Table2 或 Table3 时,这很好用,但是当我将两者合并时,销售额是被一个常数标量夸大(例如,一家公司将显示销售额恰好是应有的 16 倍)。这是怎么回事?

这是 SQL 在 Access 中显示的内容:

SELECT Table2.CompanyName,
       Sum(Table2.TotalRevenue) AS [2013 Revenue],
       Sum(Table3.TotalRevenue) AS [2014 Revenue]
FROM (Table1 INNER JOIN Table2 ON Table1.Company_ID = Table2.CompanyName)
   INNER JOIN Table3 ON Table1.Company_ID = Table3.CompanyName
GROUP BY Table2.CompanyName;

为什么要多次提取这些收入值?谢谢!

【问题讨论】:

  • 您应该考虑将TABLE2TABLE3 合并在一起,然后添加一个YEAR 字段。如果您继续增长一张表,那么将来会很乱。
  • 也许您需要先阅读一些示例来了解数据库设计。多个表的问题是您需要每年修改查询,这不利于维护。想象一下有人忘记更新或负责人不在公司。您始终可以将旧数据从主表移动到历史表以减小大小。
  • 啊,我没有考虑将来必须修改查询。这是一个很好的观点。

标签: sql ms-access query-designer


【解决方案1】:

首先您可以考虑将TABLE2TABLE3 合并在一起,然后添加一个YEAR 字段。如果您继续增长一张表,那么将来会很乱。

问题是您正在执行笛卡尔积。

[Every company] x [Sales2013] x [Sales2014]

你需要

[Every company] x [Sales2013] 
UNION
[Every company] x [Sales2014] 

不确定 Access 中的正确语法是什么,但您需要计算子查询的总计。

并且您需要LEFT JOIN 以防公司在那一年没有出售。 (就像 2014 年加入的公司)和 COALESCENULL 转换为 0

SELECT Table1.*, 
       COALESCE(T2.Revenue2013, 0)  Revenue2013, 
       COALESCE(T3.Revenue2014, 0)  Revenue2014
FROM Table1
LEFT JOIN ( SELECT CompanyName, SUM(TotalRevenue) as Revenue2013
            FROM Table2
            GROUP BY CompanyName) as T2
       ON  Table1.Company_ID = T2.CompanyName
LEFT JOIN ( SELECT CompanyName, SUM(TotalRevenue) as Revenue2014
            FROM Table3
            GROUP BY CompanyName) as T3
       ON  Table1.Company_ID = T3.CompanyName

【讨论】:

  • 谢谢,我会试试的。然而,我承认我是数据库设计的新手,但我实际上觉得多年来创建一张巨大的表更麻烦。为每年的销售额创建一个单独的表不是更清楚吗? (销售每年发布一次,不跟踪每次销售完成。)
【解决方案2】:

您获得了多个值,因为您的 Table2 和 Table3 不在公司级别。他们处于销售水平(我假设)。所以每个表都有每个客户的多条记录。在 company_id 上加入它们将导致 Table2 中的每条记录为每个 company_id 加入 Table3 中的每条记录。

如果您想更好地理解这一点,请将查询更改为 SELECT * FROM... 并使用相同的连接。您会看到,对于每条 2013 年的记录,都有许多 2014 年的记录。它没有任何意义,因此您的聚合没有多大意义。

相反,请考虑在加入之前将它们相加:

SELECT Table2.CompanyName,
       t2.TotalRevenue AS [2013 Revenue],
       t3.TotalRevenue AS [2014 Revenue]
FROM 
    Table1 
    INNER JOIN (SELECT Company_Id, CompanyName, sum(TotalRevenue) as TotalRevenue FROM Table2 GROUP BY COmpany_ID, CompanyName) as t2 ON Table1.Company_ID = T2.CompanyName)
    INNER JOIN (SELECT Company_Id, CompanyName, sum(TotalRevenue) as TotalRevenue FROM Table3 GROUP BY COmpany_ID, CompanyName) as t3 ON Table1.Company_ID = T3.CompanyName
GROUP BY T2.CompanyName;

【讨论】:

  • 谢谢,我试试看!
【解决方案3】:

发生这种情况是因为您在加入表后执行聚合。举个例子

Table 1
Company_Id, CompanyName
1           One
2           Two
3           Three

Table 2 (2013)
Company_name, State, Sales
1             CA     50
1             WA     70
2             AK     30

Table 3 (2014)
Company_name, State, Sales
1             CA     60
1             WA     90
2             AK     50

根据你的查询,首先对表2求和,获得on memory:

Company_Id, Sales_2013
1           150
2           50

与2014进行join后,得到Still on memory:

Company_Id, Sales_2013, State_2014, Sales_2014
1           150        CA           50
1           150        WA           90
2           50         AK           30

正如您在这一点上看到的那样,您有重复项。然后,进行第二次求和,最终得到

Company_Id, Sales_2013, Sales_2014
1           300         140
2           50          30

要做到这一点,您需要有一个查询:

SELECT TTable2.CompanyName,
   [2013 Revenue],
   [2014 Revenue]
FROM Table1 INNER JOIN (
    SELECT Table2.CompanyName,
        Sum(Table2.TotalRevenue) AS [2013 Revenue]
    FROM Table2
    GROUP BY Table2.CompanyName
)TTable2
ON Table1.Company_ID = TTable2.CompanyName
INNER JOIN (
    SELECT Table3.CompanyName,
        Sum(Table3.TotalRevenue) AS [2014 Revenue]
    FROM Table3
    GROUP BY Table3.CompanyName
)TTable3
ON Table1.Company_ID = TTable3.CompanyName;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多