MS Access查询错误地总计总计

时间:2016-02-26 16:45:23

标签: sql ms-access

由于表格的关系,我有一组无法成功运行的查询。这个问题困扰了我一段时间,我还没有解决它。我已经看到了类似的问题,但我无法针对我的情况实施他们的解决方案。

我认为这与我在表格中使用的联接类型有关。我已经尝试更改查询中的连接但它不起作用,因为SQL连接在那时是不明确的,并且查询不会运行。更正连接和/或使用子查询可能是我需要的解决方案,但是我无法正确实现它。

这个第一个查询由五个表组成。它的目的是为ReportYear中给出的任何人提供YTD总捐赠以及按月分类(我没有列出所有列以节省空间):

tblPartner
    IDPartner (Primary Key) 
    Other demographic info

tblDonation
    ID (Primary Key)
    IDPartner
    Amount
    Other financial info (giving method, designation, etc)

tblChildSponsorship
    ID (Primary Key)
    IDPartner
    Other sponsorship info (level, giving frequency, etc)

tblARBType (this is for tacking online giving, not really important for
            the query but it is nice to have the info displayed)

tblReportParameters (this query holds user input information to specify
    ReportYear       certain parameters of the query like date ranges or
                     donation amounts)

tblPartnertblDonationtblChildSponsorship有一对多的关系。所有三个表中的相关字段均为IDPartner

以下是来自Access的SQL:

SELECT 
    tblPartner.IDPartner, 
    IIf([tblPartner.PartnerLastName]="",  tblpartner.PartnerFirstName],[tblPartner.PartnerFirstName] & " " & [tblPartner.PartnerLastName]) AS Partner,
    tblPartner.Organization, IIf([tblARBType.ARBType]="N/A","Check",[tblARBType.ARBType]) AS ARB,
    IIf([Premium]=True,"Premium","Standard") AS SponsorLevel,
    tblPartner.Active,
    tblReportParameters.ReportYear, 
    Year([DateGiven]) AS YYYY,
    Sum(IIf(Month([DateGiven])=1,[Amount],0)) AS Jan,
    Sum(IIf(Month([DateGiven])=2,[Amount],0)) AS Feb,
    Sum(IIf(Month([DateGiven])=3,[Amount],0)) AS Mar,
    Sum(IIf(Month([DateGiven])=4,[Amount],0)) AS Apr,
    Sum(IIf(Month([DateGiven])=5,[Amount],0)) AS May,
    Sum(IIf(Month([DateGiven])=6,[Amount],0)) AS Jun,
    Sum(IIf(Month([DateGiven])=7,[Amount],0)) AS Jul,
    Sum(IIf(Month([DateGiven])=8,[Amount],0)) AS Aug,
    Sum(IIf(Month([DateGiven])=9,[Amount],0)) AS Sep,
    Sum(IIf(Month([DateGiven])=10,[Amount],0)) AS Oct,
    Sum(IIf(Month([DateGiven])=11,[Amount],0)) AS Nov,
    Sum(IIf(Month([DateGiven])=12,[Amount],0)) AS [Dec],
    Sum(IIf(Year([DateGiven]),[Amount],0)) AS YTD
FROM
    tblReportParameters, 
    (
      (
       tblARBType INNER JOIN tblPartner ON tblARBType.ID = tblPartner.ARBType
      ) 
      INNER JOIN tblChildSponsorship ON tblPartner.IDPartner = tblChildSponsorship.IDPartner
    )
    INNER JOIN tblDonation ON tblPartner.IDPartner = tblDonation.IDPartner
GROUP BY tblPartner.IDPartner, 
  IIf([tblPartner.PartnerLastName]="",[tblpartner.PartnerFirstName],[tblPartner.PartnerFirstName] & " " & [tblPartner.PartnerLastName]),
  tblPartner.Organization, 
  IIf([tblARBType.ARBType]="N/A","Check",[tblARBType.ARBType]),
  IIf([Premium]=True,"Premium","Standard"), 
  tblPartner.Active, 
  tblReportParameters.ReportYear,
  Year([DateGiven])
HAVING 
    (((Year([DateGiven]))=[ReportYear]));

对于那个文本查询墙我很抱歉。

如果我从查询中删除tblChildSponsorship,则会返回正确汇总的金额。一旦我添加了该查询,我开始获得重复的总计。在我们的系统中,合作伙伴可以赞助多个孩子,因此我认为这是由于联接类型而发生错误的地方。错误金额遵循总和的一般模式乘以所赞助的子女数量。

我已经看过使用DISTINCT AND DISTINCTROW,但这些都没有改变任何进一步导致我假设我的联接不好的假设。

如前所述,我已尝试使用各种子查询来解决此问题,但在尝试更改连接类型时,我结束了相同的结果和问题。

我意识到tblChildSponorship仅用于一个字段,但是我的第二个查询有一些细微差别,但使用相同的三个主表和相同的关系结构。如果可以确定一个解决方案,它肯定会解决另一个问题。我希望我提供了足够的信息,但如果您还有其他需要,请告诉我。

2 个答案:

答案 0 :(得分:0)

考虑将捐赠和赞助分成单独的聚合查询,然后将它们合并为一个。由于合作伙伴和儿童赞助商共享一对多关系,因此您不希望加入,然后在一个流程中汇总,或者将包括联接记录的每个组合(即多个合作伙伴ID)。因此,只需在合作伙伴级别单独汇总每个集合,然后在最后将它们连接在一起。

合作伙伴 - 捐赠汇总查询 (与上述类似,没有tblChildSponsorship加入)

SELECT tblPartner.IDPartner, 
    IIf([tblPartner.PartnerLastName]='', tblpartner.PartnerFirstName],
        [tblPartner.PartnerFirstName] & ' ' & [tblPartner.PartnerLastName]) AS Partner,
    tblPartner.Organization, 
    IIf([tblARBType.ARBType]='N/A','Check',[tblARBType.ARBType]) AS ARB,
    tblPartner.Active,
    tblReportParameters.ReportYear, 
    Year([DateGiven]) AS YYYY,
    Sum(IIf(Month([DateGiven])=1,[Amount],0)) AS Jan,
    Sum(IIf(Month([DateGiven])=2,[Amount],0)) AS Feb,
    Sum(IIf(Month([DateGiven])=3,[Amount],0)) AS Mar,
    Sum(IIf(Month([DateGiven])=4,[Amount],0)) AS Apr,
    Sum(IIf(Month([DateGiven])=5,[Amount],0)) AS May,
    Sum(IIf(Month([DateGiven])=6,[Amount],0)) AS Jun,
    Sum(IIf(Month([DateGiven])=7,[Amount],0)) AS Jul,
    Sum(IIf(Month([DateGiven])=8,[Amount],0)) AS Aug,
    Sum(IIf(Month([DateGiven])=9,[Amount],0)) AS Sep,
    Sum(IIf(Month([DateGiven])=10,[Amount],0)) AS Oct,
    Sum(IIf(Month([DateGiven])=11,[Amount],0)) AS Nov,
    Sum(IIf(Month([DateGiven])=12,[Amount],0)) AS [Dec],
    Sum(IIf(Year([DateGiven]),[Amount],0)) AS YTD
FROM tblReportParameters, 
    (tblARBType INNER JOIN tblPartner ON tblARBType.ID = tblPartner.ARBType) 
    INNER JOIN tblDonation ON tblPartner.IDPartner = tblDonation.IDPartner
GROUP BY tblPartner.IDPartner, 
  IIf([tblPartner.PartnerLastName]='', [tblpartner.PartnerFirstName],
      [tblPartner.PartnerFirstName] & ' ' & [tblPartner.PartnerLastName]),
  tblPartner.Organization, 
  IIf([tblARBType.ARBType]='N/A','Check',[tblARBType.ARBType]),
  tblPartner.Active, 
  tblReportParameters.ReportYear,
  Year([DateGiven])
HAVING (((Year([DateGiven]))=[ReportYear]));

赞助汇总查询 (接受[Premium]的最新条目

SELECT IDPartner, Last(IIf([Premium]=True,'Premium','Standard')) AS SponsorLevel,
FROM tblChildSponsorship
GROUP BY IDPartner;

最终加入查询

SELECT d.IDPartner, d.Partner, d.Organization, d.ARB, d.Active, d.ReportYear, d.YYYY
       d.Jan, d.Feb, d.Mar, d.Apr, d.May, d.Jun, 
       d.Jul, d.Aug, d.Sep, d.Oct, d.Nov, d.Dec, d.YTD,
       s.SponsorLevel           
FROM DonationsAgg d
INNER JOIN SponsorshipAgg s
ON d.IDPartner = s.IDPartner

顺便说一下,可以想象使用派生表(FROMJOIN子句中的嵌套select语句)将所有上述查询处理成一个查询。但MS Access允许存储的查询,这可能有助于代码源的可维护性。

SELECT DonationsAgg.IDPartner, DonationsAgg.Partner, 
       DonationsAgg.Organization, DonationsAgg.ARB, DonationsAgg.Active, 
       DonationsAgg.ReportYear, DonationsAgg.YYYY
       DonationsAgg.Jan, DonationsAgg.Feb, DonationsAgg.Mar, 
       DonationsAgg.Apr, DonationsAgg.May, DonationsAgg.Jun, 
       DonationsAgg.Jul, DonationsAgg.Aug, DonationsAgg.Sep,
       DonationsAgg.Oct, DonationsAgg.Nov, DonationsAgg.Dec,
       DonationsAgg.YTD, SponsorshipAgg.SponsorLevel
FROM
  (...Partner-Donation Aggregate Query...) As DonationsAgg
INNER JOIN
  (...Sponsorship Aggregate Query...) As SponsorshipAgg
ON DonationsAgg.IDPartner = SponsorshipAgg.IDPartner

答案 1 :(得分:-1)

这不是最好的选择,但你可以通过子计数来计算总和:

SELECT 
    ..
    ,Sum(IIf(Month([DateGiven])=1,[Amount],0)) / count(distinct tblChildSponsorship.ID) AS Jan,
    ..