0

我有三个与我网站的文章部分相关的表格。如果作者文章阅读的次数,我需要根据数量显示顶级作者。我使用基本的三个表来存储此信息。

Article具有与文章相关的所有详细信息,作者信息存储在Authors,当用户查看特定文章时,我会更新或插入新记录Popularity

以下是样本数据:

Articles

ArticleID  Title             Desc  AuthorID
---------  ----------------  ----  --------
1          Article One       ....  100
2          Article Two       ....  200
3          Article Three     ....  100
4          Article Four      ....  300
5          Article Five      ....  100
6          Article Six       ....  300
7          Article Seven     ....  500
8          Article Eight     ....  100
9          Article Nine      ....  600

Authors

AuthorID  AuthorName
--------  ------------
100       Author One
200       Author Two
300       Author Three
400       Author Four
500       Author Five
600       Author Six

Popularity

ID  ArticleID  Hits
--  ---------  ----
1   1          20
2   2          50
3   5          100
4   3          11
5   4          21

我正在尝试使用以下查询来获取 TOP 10 作者:

SELECT TOP 10    AuthorID 
      ,au.AuthorName
      ,ArticleHits
      ,SUM(ArticleHits) 
FROM Authors au 
JOIN Articles ar
  ON au.AuthorID = ar.ArticleAuthorID
JOIN  Popularity ap
  ON ap.ArticleID = ar.ArticleID
GROUP BY AuthorID,1,1,1

但这会产生以下错误:

消息 164,级别 15,状态 1,第 12 行
每个 GROUP BY 表达式必须包含至少一个不是外部引用的列。

4

3 回答 3

3

SQL Server 要求列表中的任何列都SELECT必须在GROUP BYcluase 或聚合函数中。以下查询似乎正在工作,正如您所看到的,我包含了 a ,其中包含列表中不在聚合函数中GROUP BY au.AuthorID, au.AuthorName的两列:SELECT

SELECT top 10 au.AuthorID 
      ,au.AuthorName
      ,SUM(Hits) TotalHits
FROM Authors au 
JOIN Articles ar
  ON au.AuthorID = ar.AuthorID
JOIN  Popularity ap
  ON  ap.ArticleID = ar.ArticleID
GROUP BY au.AuthorID, au.AuthorName
order by TotalHits desc

请参阅SQL Fiddle with Demo

我不确定你是否想要HitsSELECT声明中,因为你将不得不这样GROUP BY做。这可能会改变Sum(Hits)每篇文章的结果,因为如果每个条目中的点击次数不同,您将无法获得准确的总和。

于 2013-02-03T14:03:39.140 回答
2

我会这样做。首先弄清楚你的前十位作者是谁,然后去获取名字(以及你想要的任何其他列)。对于这个查询,这并不是一个巨大的差异,但是随着您的输出列表要求的增加,所有这些分组都会变得更加复杂和昂贵。

;WITH TopAuthors(AuthorID, ArticleHits) AS
(
  SELECT TOP (10) a.AuthorID, SUM(p.Hits)
    FROM dbo.Authors AS a
    INNER JOIN dbo.Articles AS ar
    ON a.AuthorID = ar.AuthorID
    INNER JOIN dbo.Popularity AS p
    ON ar.ArticleID = p.ArticleID
    ORDER BY SUM(p.Hits) DESC
)
SELECT t.AuthorID, a.AuthorName, t.ArticleHits
FROM TopAuthors AS t
INNER JOIN dbo.Authors AS a
ON t.AuthorID = a.AuthorID
ORDER BY t.ArticleHits DESC;

对于这个特定的查询,bluefeet 的版本可能更有效。但是,如果您在输出中添加额外的列(例如,作者表中的更多信息),那么分组可能会超过我提供的额外搜索或扫描。

于 2013-02-03T15:48:09.223 回答
1

与聚合函数一样多的列必须存在于 group by 子句中。在您的情况下,AuthorID、au.AuthorName、ArticleHits 也应该存在。因此 group by 语句将变为
GROUP BY AuthorID, au.AuthorName, ARticleHits
这会有所帮助。

于 2013-02-03T14:00:50.433 回答