【问题标题】:How to average only fields whose records meet certain criteria in Access?如何在Access中仅对记录符合某些条件的字段进行平均?
【发布时间】:2011-12-15 18:54:43
【问题描述】:

我有一个名为 Reviewer Score Averages 的 ACCESS 表,其中包含个人完成的公司评论的信息,结构如下:

ID |审稿人 |公司 |点评评分

Company 字段只能包含四个值:

星巴克
麦当劳
绿山
驯鹿

我们有一个 SQL 查询,它对给定审阅者的所有 ReviewScores 进行平均,但想要对其进行修改,以便它也计算除 CARIBOU 以外的公司的所有 ReviewScores 的平均值。

原始的功能查询是:

SELECT [Reviewer Score Averages].Reviewer, 
       Reviewers.[Last Name] & ", " & [First Name] AS Name, 
       Reviewers.[Email Address], 
       Avg([Reviewer Score Averages].[1stReviewScore]) AS AvgOfAllReviews;

目前无法使用的编辑版本是:

SELECT [Reviewer Score Averages].Reviewer, 
       Reviewers.[Last Name] & ", " & [First Name] AS Name, 
       Reviewers.[Email Address], 
       Avg([Reviewer Score Averages].[1stReviewScore]) AS AvgOfAllReviews, 
       Avg([Reviewer Score Averages].[1stReviewScore] 
WHERE [Reviewer Score Averages].[Company] = 'STARBUCKS' OR 'MCDONALDS' OR 'GREENMOUNTAIN') AS AvgOfNonCaribou;

当我尝试运行此代码时,我收到一条错误消息,提示我缺少一个运算符:我查看了 Microsoft 的 documentation 的 WHERE 语法,但我没有看到任何明显的内容不见了。

这是 Access 2003 数据库中的一个表。

我做错了什么?我在滥用 WHERE 吗?我的语法错了吗?我错过了什么吗?有没有更好的方法来解决这个问题?

非常感谢您的帮助。

【问题讨论】:

  • 我们遗漏了一些细节,尤其是FROM 子句,它可以揭示表[Reviewer Score Averages]Reviewers 的连接方式,而GROUP BY 子句也很有帮助。理想情况下,您会发布表架构、测试数据和预期结果:)

标签: sql ms-access


【解决方案1】:

缺少的运算符肯定在WHERE [Reviewer Score Averages].[Company] = 'STARBUCKS' OR 'MCDONALDS' OR 'GREENMOUNTAIN';正如其他人指出的那样,在这种情况下您需要 IN 运算符:WHERE [Reviewer Score Averages].[Company] IN ('STARBUCKS', 'MCDONALDS' , 'GREENMOUNTAIN')

但是,我认为您不能将 WHERE 子句放在 AVG 子句中。我没有 Access 2003,所以我无法为您确认这一点,但在 2010 年,这会产生所需的结果,并将帮助您找出适合您的真实表的正确语法:

SELECT AVG(ReviewScore), AVG(SWITCH(COMPANY = 'Caribou', NULL, 1=1, ReviewScore)) as NotCaribou
FROM table1

【讨论】:

  • 我想就是这样:SWITCH 似乎是要走的路。由于其他原因,我正在处理的真实表的实际代码仍然存在错误,但我已经用我作为示例设置的 Coffee 数据库测试了这个块,它就像一个梦一样工作。非常感谢您的帮助,@sfuqua。
【解决方案2】:

为什么不直接做:

...WHERE [Reviewer Score Averages].[Company] <> 'CARIBOU'

或者,制作您的原创作品:

...WHERE [Reviewer Score Averages].[Company] = 'STARBUCKS' 
      OR [Reviewer Score Averages].[Company] = 'MCDONALDS' 
      OR [Reviewer Score Averages].[Company] = 'GREENMOUNTAIN'

编辑:充实@Remou 的评论:

...WHERE [Reviewer Score Averages].[Company] IN ('STARBUCKS', 'MCDONALDS', 'GREENMOUNTAIN')

【讨论】:

  • Access 对 IN 也很满意。
  • 两个调用都很好——这些比我原来的代码更优雅,并且修复了我的部分语法问题。不过,我认为 sfuqua 是对的,更根本的问题是 AVG 子句中的 WHERE 子句。
【解决方案3】:

不要将SWTICHAVG 函数内联,而是考虑使用两个视图,例如

CREATE VIEW ReviewsAvgsAll
AS
SELECT Reviewer, 
       Avg([1stReviewScore]) AS AvgOfReviews
  FROM [Reviewer Score Averages] AS RSA
 GROUP 
    BY Reviewer;

CREATE VIEW ReviewsAvgsNonCARIBOU
AS
SELECT Reviewer, 
       Avg([1stReviewScore]) AS AvgOfReviews
  FROM [Reviewer Score Averages] AS RSA
 WHERE Company <> 'CARIBOU';
 GROUP 
    BY Reviewer;

以通常的方式创建这些视图;注意CREATE VIEW 语法需要ANSI-92 Query Syntax

然后以通常的方式将Reviewers 连接到ReviewsAvgsAllsemi-joinReviewsAvgsNonCARIBOU。您已经省略了 FROM 子句,但假设公共属性是 Reviewer 它可能看起来像这样:

SELECT RAA.Reviewer, 
       R.[Last Name] & ", " & [First Name] AS Name, 
       R.[Email Address], 
       RAA.AvgOfReviews AS AvgOfAllReviews, 
       RAN.AvgOfReviews AS AvgOfNonCARIBOUReviews
  FROM Reviewers AS R       
       INNER JOIN ReviewsAvgsAll AS RAA
          ON R.Reviewer = RA.Reviewer
       INNER JOIN ReviewsAvgsNonCARIBOU AS RAN
          ON R.Reviewer = RAN.Reviewer
UNION
SELECT RAA.Reviewer, 
       R.[Last Name] & ", " & [First Name] AS Name, 
       R.[Email Address], 
       RAA.AvgOfReviews AS AvgOfAllReviews, 
       -1 AS AvgOfNonCARIBOUReviews
  FROM Reviewers AS R       
       INNER JOIN ReviewsAvgsAll AS RAA
          ON R.Reviewer = RA.Reviewer
 WHERE NOT EXISTS (
                   SELECT * 
                     FROM ReviewsAvgsNonCARIBOU AS RAN
                    WHERE R.Reviewer = RAN.Reviewer
                  );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-23
    • 2023-03-21
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 2011-12-17
    相关资源
    最近更新 更多