如何将此SQL语句修复为AVERAGE来自另一个表的多行?

时间:2009-09-29 01:41:25

标签: sql sql-server tsql sql-server-2008

我在下面的SQL中遇到了一些问题。

SELECT * 
  FROM (SELECT tbrm_Article.ArticleID, 
               tbrm_Article.CountryID,
               tbrm_Article.CategoryID,
               tbrm_Article.Title,
               tbrm_Article.ArticleDetail,
               tbrm_Article.Source,
               tbrm_Article.ArticleDateTimeAdded,
               tbrm_Article.ViewCount,
               tbrm_Article.CommentCount,
               tbrm_CountryList.CountryName AS CountryName,
               tbrm_CountryList.CountryImage AS CountryImage,
               tbrm_CategoryList.CategoryName AS CategoryName,
               tbrm_CategoryList.CategoryImage AS CategoryImage,
               aspnet_Users.UserName AS UserName,
               AVG(tbrm_Votes.True) OVER() AS Truth,
               AVG(tbrm_Votes.False) OVER() AS False,
               ROW_NUMBER() OVER (ORDER BY tbrm_Article.ArticleDateTimeAdded DESC) AS RowRank      
          FROM tbrm_Article 
          JOIN tbrm_CountryList ON tbrm_Article.CountryID = tbrm_CountryList.CountryID 
          JOIN tbrm_CategoryList ON tbrm_Article.CategoryID = tbrm_CategoryList.CategoryID 
          JOIN aspnet_Users ON tbrm_Article.UserID = aspnet_Users.UserID 
          JOIN tbrm_Votes ON tbrm_Article.ArticleID = tbrm_Votes.ArticleID)  Article
   WHERE Article.RowRank > @PageIndex AND RowRank <= (@PageIndex + @PageSize)
ORDER BY Article.ArticleDateTimeAdded DESC

除了两个AVG语句之外,一切正常。它不是仅对一个适用的相关文章ID进行平均,而是返回整个值表的平均值。有什么想法解决这个问题的最佳方法吗?我正在使用SQL Server 08.

2 个答案:

答案 0 :(得分:2)

如果您使用聚合函数,例如avg,则需要在partition by子句中使用over,或者在{{{{}}中包含所选的不是聚合的列1}}子句。

像这样:

group by

例如,如果您只想按SELECT * FROM ( SELECT tbrm_Article.ArticleID, tbrm_Article.CountryID, tbrm_Article.CategoryID, tbrm_Article.Title, tbrm_Article.ArticleDetail, tbrm_Article.Source, tbrm_Article.ArticleDateTimeAdded, tbrm_Article.ViewCount, tbrm_Article.CommentCount, tbrm_CountryList.CountryName AS CountryName, tbrm_CountryList.CountryImage AS CountryImage, tbrm_CategoryList.CategoryName AS CategoryName, tbrm_CategoryList.CategoryImage AS CategoryImage, aspnet_Users.UserName AS UserName, AVG(tbrm_Votes.True) AS Truth, AVG(tbrm_Votes.False) AS False, ROW_NUMBER() OVER (ORDER BY tbrm_Article.ArticleDateTimeAdded DESC) AS RowRank FROM tbrm_Article INNER JOIN tbrm_CountryList ON tbrm_Article.CountryID = tbrm_CountryList.CountryID INNER JOIN tbrm_CategoryList ON tbrm_Article.CategoryID = tbrm_CategoryList.CategoryID INNER JOIN aspnet_Users ON tbrm_Article.UserID = aspnet_Users.UserID INNER JOIN tbrm_Votes ON tbrm_Article.ArticleID = tbrm_Votes.ArticleID GROUP BY tbrm_Article.ArticleID, tbrm_Article.CountryID, tbrm_Article.CategoryID, tbrm_Article.Title, tbrm_Article.ArticleDetail, tbrm_Article.Source, tbrm_Article.ArticleDateTimeAdded, tbrm_Article.ViewCount, tbrm_Article.CommentCount, tbrm_CountryList.CountryName, tbrm_CountryList.CountryImage, tbrm_CategoryList.CategoryName, tbrm_CategoryList.CategoryImage, aspnet_Users.UserName ) Article WHERE Article.RowRank > @PageIndex AND RowRank <= (@PageIndex + @PageSize) ORDER BY Article.ArticleDateTimeAdded DESC 进行,则可以删除CountryName子句并使用:

group by

答案 1 :(得分:0)

Cunners,

我认为如果你解释你想要的东西会有所帮助,尤其是图片的分页部分。如果你只是将一个PARTITION BY子句添加到AVG()表达式的OVER子句中,你仍然会为每一次投票获得一行,我怀疑这是你想要的。

如果我不得不猜测,我猜你想要这样的东西,但我不知道你的连接的基数(或其他很多),所以这只是猜测。

WITH ARTICLE AS (
  SELECT
  tbrm_Article.ArticleID, 
  tbrm_Article.CountryID,
  tbrm_Article.CategoryID,
  tbrm_Article.Title,
  tbrm_Article.ArticleDetail,
  tbrm_Article.Source,
  tbrm_Article.ArticleDateTimeAdded,
  tbrm_Article.ViewCount,
  tbrm_Article.CommentCount,
  tbrm_CountryList.CountryName AS CountryName,
  tbrm_CountryList.CountryImage AS CountryImage,
  tbrm_CategoryList.CategoryName AS CategoryName,
  tbrm_CategoryList.CategoryImage AS CategoryImage,
  aspnet_Users.UserName AS UserName,
  Truth,
  False,
  ROW_NUMBER() OVER (ORDER BY tbrm_Article.ArticleDateTimeAdded DESC) AS RowRank

  FROM

  tbrm_Article INNER JOIN
  tbrm_CountryList ON tbrm_Article.CountryID = tbrm_CountryList.CountryID INNER JOIN
  tbrm_CategoryList ON tbrm_Article.CategoryID = tbrm_CategoryList.CategoryID INNER JOIN
  aspnet_Users ON tbrm_Article.UserID = aspnet_Users.UserID 
  CROSS APPLY (
    SELECT tbrm_Votes.ArticleID, AVG(tbrm_Votes.True), AVG(tbrm_Votes.False)
    FROM tbrm_Votes
    WHERE tbrm_Article.ArticleID = Votes.ArticleID
    GROUP BY tbrm_Votes.ArticleID
  ) AS Votes(ArticleID,Truth,False)
)
  SELECT * FROM ARTICLE
  WHERE ARTICLE.RowRank > @PageIndex AND ARTICLE.RowRank <= (@PageIndex + @PageSize)
  ORDER BY ARTICLE.ArticleDateTimeAdded DESC