2012-07-06 6 views
8

に与えられていない列を含めるは、効率的にSQLのグループによってクエリー

Id INTEGER 
Name VARCHAR(50) 

表B Iは、各FkId値のoccurrancesをカウントしたい

Id INTEGER 
FkId INTEGER ; Foreign key to Table A 

SELECT FkId, COUNT(FkId) 
FROM B 
GROUP BY FkId 

ここでは、単に名前をTable Aから出力したいだけです。

これは動作しません。

SELECT FkId, COUNT(FkId), a.Name 
FROM B b 
INNER JOIN A a ON a.Id=b.FkId 
GROUP BY FkId 

a.Nameためには、(is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clauseエラーが発生します)GROUP BY句に含まれていません。

点は、そのエラーメッセージが、いくつかの例のためのようにかなりの数のマッチがあり、この

FkId Count Name 
1  42  Ronald 
2  22  John 

ように出力するように、この

FkId Count 
1  42 
2  25 

ような出力から移動させることですhttps://stackoverflow.com/a/6456944/141172には、「1ではなくテーブルに3つのスキャンが生成されるため、拡大縮小されません」というコメントがあります。クエリ出力で:

にはどうすれば効率的には(FkIdから1関係1を持っている)に入社Table Bからフィールドを含めることができますか?

+0

サンプルデータと希望の結果を表示できますか? FkIdごとに複数の固有の名前が存在するかどうかを理解するのは苦労しています。 –

+0

FkIdごとに一意の名前が1つしかありません。ポイントは、FkIdの横に名前を表示するだけなので、結果を見ているユーザーは「Person 1が42回出現しました」と表示されず、「Ronaldという名前のPerson 1が42回出現しました」と表示されます。 –

+1

名前をグループに追加するだけではどうですか? –

答えて

12

あなたはこのような何かを試すことができますTable Aに移動して、Table Aから最終結果セットにいくつかの列を追加します。

+0

これは、私がリンクしている解決策とほぼ同じです。コメントには、「1ではなく3つのスキャンが生成されるので、拡大縮小しません」というコメントがあります。その解説者が示唆しているように、このソリューションは本当に3回のテーブルスキャンを行いますか? –

+5

@EricJ .:クエリをコピーしてSQL Server Mgmt Studioで実行し、「実際の実行計画」を有効にしてください。** NO ** ** 3つのテーブルスキャンは実行されません.....あなたがリンクしている答えのコメントは正しくあります。なぜなら、そこにあるクエリは** 2つの余分な** '(SELECT ....)'サブクエリです - **これらの**はそれぞれ1つのテーブルスキャンを追加しますグループ化に使用されるCTE!) –

+1

+1実際の実行計画を使用してパフォーマンスを診断する場合。 :-) –

3

グループにフィールドを追加しようとしましたか?あなたのTable Bにカウント/グループ化を処理するために

;WITH GroupedData AS 
    (
     SELECT FkId, COUNT(FkId) As FkCount 
     FROM B 
     GROUP BY FkId 
    ) 
    SELECT gd.*, a.Name 
    FROM GroupedData gd 
    INNER JOIN dbo.A ON gd.FkId = A.FkId 

CTE(共通テーブル式)を作成し、(FkIdごとに1行)その結果を参加:

SELECT FkId, COUNT(FkId), a.Name 
FROM B b 
INNER JOIN A a ON a.Id=b.FkId 
GROUP BY FkId,a.Name 
0
select t3.Name, t3.FkId, t3.countedFkId from (a t1 
    join (select t2.FkId, count(FkId) as countedFkId from b t2 group by t2.FkId) 
    on t1.Id = t2.FkId) t3; 
+1

' {} 'not 'コードブロックを強調表示します。そしてキャリッジリターンを恐れてはいけません。また、私はこのクエリが解析されたとは思わない(派生テーブルに別名が必要)。 –

+0

ああ、アドバイスありがとう。ここでの構文はまだ新しいです:)そして、あなたは、派生テーブルのエイリアスが必要だと思います。 – germi

関連する問題