【问题标题】:MS Access SQL Query using Sum() and Count() gives incorrect results使用 Sum() 和 Count() 的 MS Access SQL 查询给出不正确的结果
【发布时间】:2012-08-02 20:43:24
【问题描述】:

我遇到了一个查询,它返回的结果与现实相去甚远(这不仅完全没有意义,而且我还可以使用过滤器计算出正确的答案)。

我正在为工作构建一个 KPI 数据库,此查询按期间按员工返回 KPI。我有一个非常相似的查询,从中派生出这个查询,它按部门按周期返回 KPI,它给出了我使用电子表格计算的确切结果。我真的不知道这里会发生什么。基本上,我想总结maintenances 表中的一些度量,例如temps_requete_mintemps_analyse_mintemps_maj_mintemps_rap_min,然后创建一个小计并将这些度量表示为小时(度量以分钟为单位,因此除以 60)。

SELECT 
    [anal].[prenom] & " " & [anal].[nom] AS Analyste, 
    maint.periode, maint.annee, 
    Round(Sum(maint.temps_requete_min)/60,2) AS REQ, 
    Round(Sum(maint.temps_analyse_min)/60,2) AS ANA, 
    Round(Sum(maint.temps_maj_min)/60,2) AS MAJ, 
    Round(Sum(maint.temps_rap_min)/60,2) AS RAP,       
    Round((Sum(maint.temps_requete_min)+Sum(maint.temps_analyse_min)+Sum(maint.temps_maj_min)+Sum(maint.temps_rap_min))/60,2) AS STOTAL, 
    Count(maint.periode) AS Nombre, 
    a.description

FROM 
    rapports AS rap, 
    analyste AS anal, 
    maintenances AS maint, 
    per_annuelle, 
    annees AS a

WHERE 
    (((rap.id_anal_maint)=anal.id_analyste) And
    ((maint.id_fichier)=rap.id_rapport) And 
    ((maint.maint_effectuee)=True) And 
    ((maint.annee)=per_annuelle.annee) And
    ((per_annuelle.annee)=a.annees))

GROUP BY 
    [anal].[prenom] & " " & [anal].[nom], 
    maint.periode, 
    maint.annee, 
    a.description, 
    anal.id_analyste

ORDER BY 
    maint.annee, maint.periode;

所有措施都比应有的水平高出许多数量级。我怀疑我的 Count() 是错误的,但我看不出总和会有什么问题:|

编辑: 最后我提出了这个查询,它显示了我使用 Excel 根据 cmets 中给出的建议和提供的答案计算出的相同度量。非常感谢大家。然而,我想知道的是,为什么使用显式连接而不是隐式连接会有所不同(PK 上的WHERE 子句)。

SELECT
    maintenances.periode,
    [analyste].[prenom] & " " & analyste.nom,
    Round(Sum(maintenances.temps_requete_min)/60,2) AS REQ,
    Round(Sum(maintenances.temps_analyse_min)/60,2) AS ANA, 
    Round(Sum(maintenances.temps_maj_min)/60,2) AS MAJ, 
    Round(Sum(maintenances.temps_rap_min)/60,2) AS RAP,
    Round((Sum(maintenances.temps_requete_min)+Sum(maintenances.temps_analyse_min)+Sum(maintenances.temps_maj_min)+Sum(maintenances.temps_rap_min))/60,2) AS STOTAL, 
    Count(maintenances.periode) AS Nombre

FROM 
    (maintenances INNER JOIN rapports ON maintenances.id_fichier = rapports.id_rapport)
    INNER JOIN analyste ON rapports.id_anal_maint = analyste.id_analyste

GROUP BY analyste.prenom, maintenances.periode

【问题讨论】:

  • 为什么anal.id_analyste 在您的GROUP BY 子句中?
  • 您是否尝试过使用显式而不是隐式连接?我怀疑你得到了重复记录。
  • many orders of magnitude higher than what they should be 表示这些表没有正确链接在一起,并且您在某处有一个笛卡尔积 - 或者返回的数据比您预期的要多。尝试在没有 SUM()COUNT()GROUP BY 的情况下运行查询,看看返回了什么数据...
  • @JamesL.:否则 Access 会在 GROUP BY 子句中抱怨它是 not。然而,这在查询中没有意义:|
  • 是的,这没有意义,因为它不在select 列表中。当计算字段中使用表的任何字段时,Access 可能会强制您包含表的主键。

标签: sql ms-access-2007


【解决方案1】:

在这种情况下,问题通常是您的连接将多个维度组合在一起。您最终会跨两个或多个类别进行交叉产品。

解决方法是沿每个维度独立进行汇总。这意味着“from”子句包含带有分组依据的子查询,然后将它们连接在一起。 group by 将从外部查询中消失。

这建议有一个子查询,例如:

from (select maint.periode, maint.annee,
             Round(Sum(maint.temps_requete_min)/60,2) AS REQ, 
             Round(Sum(maint.temps_analyse_min)/60,2) AS ANA, 
             Round(Sum(maint.temps_maj_min)/60,2) AS MAJ, 
             Round(Sum(maint.temps_rap_min)/60,2) AS RAP,       
             Round((Sum(maint.temps_requete_min)+Sum(maint.temps_analyse_min) +Sum(maint.temps_maj_min)+Sum(maint.temps_rap_min))/60,2) AS STOTAL, 
             Count(maint.periode) AS Nombre, 
      from maintenances maint
      group by maint.periode, maint.annee
     ) m

我说“例如”是因为没有表格布局,很难准确看出问题出在哪里以及确切的解决方案是什么。

【讨论】:

  • 感谢您的回答。我肯定会在明天早上的第一件事上尝试一下,然后给你反馈:)
  • +1 这是一个很好的答案。此外,您可能需要考虑除以 60.0 而不是 60(以防这些列中的任何一个是整数类型,并且没有任何特定转换为非整数数字。)从您正在执行 SUMCOUNT 聚合,并在那里查看结果。通常,它是对另一个引入“重复”行的表的 JOIN。
  • 授予复选标记,因为我使用了类似的逻辑来构建我的最终查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多