使用连接的三个表中的不同行

时间:2013-02-03 13:56:31

标签: sql-server sql-server-2008

我有三个与我网站文章部分相关的表格。我需要根据数字显示最佳作者,如果作者文章读取的时间。我使用基本的三个表来存储此信息。

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

但这会产生以下错误:

  

Msg 164,Level 15,State 1,Line 12
每个GROUP BY表达式必须包含至少一个不是外部引用的列。

3 个答案:

答案 0 :(得分:3)

SQL Server要求SELECT列表中的所有列都必须位于GROUP BY cluase或聚合函数中。以下查询似乎正在运行,您可以看到我添加了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

我不确定您是否需要Hits语句中的SELECT,因为您必须GROUP BY它。这可能会改变每篇文章的Sum(Hits),因为如果每个条目中的匹配不同,您将无法获得准确的总和。

答案 1 :(得分: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的版本可能更有效。但是,如果您在输出中添加其他列(例如,authors表中的更多信息),则分组可能会超过我提供的其他搜索或扫描。

答案 2 :(得分:1)

由于聚合函数中存在许多列,因此必须在group by子句中出现。在您的情况下,AuthorID,au.AuthorName,ArticleHits也应该出现。因此,group by声明将成为
    GROUP BY AuthorID,au.AuthorName,ARticleHits
这会有所帮助。