0

私のウェブサイトの記事セクションに関連する3つのテーブルがあります。著者の記事を読んだ回数に基づいて、トップの著者を表示する必要があります。この情報を保存するために、基本的な3つのテーブルを使用します。

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

ただし、これにより次のエラーが発生します。

メッセージ164、レベル15、状態1、行12
各GROUP BY式には、外部参照ではない列が少なくとも1つ含まれている必要があります。

4

3 に答える 3

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を参照してください。

ステートメントHitsにが必要かどうかはわかりません。各エントリのヒット数が異なる場合、正確な合計が得られないため、これにより各記事が変更される可能性があります。SELECTGROUP BYSum(Hits)

于 2013-02-03T14:03:39.140 に答える
2

私ならこうします。最初にトップ 10 の著者を特定し、次に名前を取得します (およびその他の列を取得します)。このクエリの場合、大きな違いはありませんが、出力リストの要件が増えるにつれて、グループ化がより複雑になり、コストがかかる可能性があります。

;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 テーブルからの詳細情報)、グループ化は、私が提示した追加のシークまたはスキャンを上回る可能性があります。

于 2013-02-03T15:48:09.223 に答える
1

Aggregate 関数で存在する列と同じ数の列が、group by 句に存在する必要があります。あなたの場合、AuthorID、au.AuthorName、ArticleHits も存在する必要があります。したがって、group by ステートメントは
GROUP BY AuthorID, au.AuthorName, ARticleHits に
なります。

于 2013-02-03T14:00:50.433 に答える