2013-02-03 70 views
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 

我嘗試使用下面的查詢來獲得前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
Each GROUP BY expression must contain at least one column that is not an outer reference.

回答

3

SQL Server要求SELECT列表中的任何列必須位於GROUP BY線索或集合函數中。下面的查詢似乎是工作,你可以看到我包括了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

我不知道您是否想在SELECT聲明中使用Hits,因爲您將不得不GROUP BY它。這可能會改變每篇文章的Sum(Hits),因爲如果每個條目中的命中不同,您將無法獲得準確的總和。

+0

我會基於性能標記你的答案是正確的,我不知道爲什麼即使當我寫出幾乎類似的查詢出來的挫折我爲什麼我得到錯誤,我嘗試了很多事情,結束了堆棧,反正它的作品和感謝您的答覆。我不得不使用SUM(點擊)'來計算哪些作者的文章是最讀的..我無法得到你的答案的最後部分關於準確的結果我的數據是類似於我所提到的作爲問題 – Learning

1

正如許多列那些必須存在的組按條款。在你的情況下,AuthorID,au.AuthorName,ArticleHits也應該在場。因此,集團的聲明將成爲
GROUP BY AuthorID,au.AuthorName,ARticleHits
這將有所幫助。

+0

我覺得你的第一句話是倒退了。選擇列表中的聚合函數中的列不屬於group by子句。聚合函數中的列* NOT *必須出現在group by中。 –

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表的更多信息),分組可能會超過我提供的額外搜索或掃描。

+0

性能的一部分總是我的關注,但在這種情況下,我可能只需要authorID,AuthorName,點擊數和語言ID ...我會嘗試你的CTE解決方案,看看是否運作良好.. UpVote for your solution ... – Learning