2

これまでTSQLを使用したことはありませんが、とにかくSOデータダンプを調べたいと思いました。したがって、これはおそらく新人の質問です。私は答えを検索しようとしましたが、私がやろうとしていることの専門用語がわかりません。適切なキーワードがない場合にのみ、検索は非常に優れています。

私の目標は、スコアが0の質問の数、スコアが1の質問の数、スコアが2の質問の数などを調べることです。私はそれらの個々の数を見つけるためにクエリを書くことができます、問題ありません。ただし、ループを含むクエリを実行できるようにしたいと思います。これが私が今まで使っているものです:

DECLARE @counter int
SET @counter = 0
WHILE @counter < 3
BEGIN
    SELECT
        COUNT(*)
    FROM
        Posts
    WHERE
        PostTypeId = 1
    AND
        Score = @counter

    SET @counter = @counter + 1
END

編集:最終的な目標は、[0、3]から[-100、1000]または既存のすべての質問に答えるために必要なものに拡張することです)明らかに、私の問題は、ループの各サイクルでカウントを取得していることですそしてそれで何もしません。@counter現在、私が得た結果は、最初に設定されたものの数だけです。反復回数は関係ありません。結果をどこかに保存して、次のように表示することは可能ですか?

+ ------- + -------------------------------- +
| スコア| NumberOfQuestionsWithThatScore |
+ ------- + -------------------------------- +
| -10 | 111 |
+ ------- + -------------------------------- +
| -9 | 0 |
+ ------- + -------------------------------- +
| -8 | 248 |
+ ------- + -------------------------------- +
| ... | ... |
+ ------- + -------------------------------- +

編集:適度にクリアな表示で問題ありません。上記の表は単なるサンプルです。編集2:継続的な混乱を解消するためにテーブルのデザインを変更しました)

もしそうなら、これは何と呼ばれ、どのように行われますか?

4

3 に答える 3

6

リストした出力は、行を列データに変換する標準のピボットクエリです。

SELECT SUM(CASE WHEN p.score = 0 THEN 1 ELSE 0 END) AS ScoreOfZero,
       SUM(CASE WHEN p.score = 1 THEN 1 ELSE 0 END) AS ScoreOfOne,
       SUM(CASE WHEN p.score = 2 THEN 1 ELSE 0 END) AS ScoreOfTwo
  FROM POSTS p
于 2010-09-16T15:54:42.960 に答える
6

実際には、これを1回のパスで実行できます...

SELECT COUNT(*) AS Total, MAX(Score) AS Score
FROM Posts
WHERE PostTypeId = 1 And Score <= 3
Group By Score

それはあなたに次のような素敵なテーブルを与えるはずです:

Score   Total
0       2490
1       2904
2       2110

構文を検証するために、今すぐDBの前ではなく、カフからそれを痛めます。より良いアイデアを得るために「GroupBy」を検索してください。

@OMG Poniesが指摘しているように、これは元々のようにピボットされていません。単一の列が必要な場合は、SELECTとSUMを使用してそれを行う必要があります。

于 2010-09-16T15:52:20.443 に答える
1

例1:これは、元の方法に基づいた具体的なソリューションですが、ゼロカウントスコアを含む、最小から最大までのすべてのスコアカウントの行を提供します。

--Posts per score, with zeros.

declare @minScore int
declare @maxScore int
declare @current int
declare @postType int

set @postType = 1

set @minScore = (select MIN(Score) from Posts where PostTypeId = @postType)
set @maxScore = (select MAX(Score) from Posts where PostTypeId = @postType)

set @current = @minScore

create table #myTemp (Score int, PostsCount int) 

insert into #myTemp
select Score, count(*) from Posts group by Score

while @current < @maxScore
begin
  insert into #myTemp
  select @current, 0
    where not exists (select 1 from #myTemp where Score = @current and PostTypeId = @postType)
  set @current = @current + 1
end

select * from #myTemp order by Score
​

例2:列をスコアとして使用する安っぽい動的SQLアプローチ。各列はサブクエリです。免責事項:SEDEはすべてを実行しているようですが、結果は得られません。代わりselect @dynSQLに最後に実行してから実行すると、データが取得されます。

-- Dynamic SQL count of all posts for a score

declare @minScore int
declare @maxScore int
declare @current int
declare @postType int
declare @dynSQL nvarchar(MAX)

set @postType = 1

set @minScore = (select MIN(Score) from Posts where PostTypeId = @postType)
set @maxScore = (select MAX(Score) from Posts where PostTypeId = @postType)

set @current = @minScore

set @dynSQL = 'select '

while @current <= @maxScore
begin
    set @dynSQL = @dynSQL 
                  + '(select count(*) from Posts where PostTypeId = ' 
                  + convert(varchar,@postType) + ' and Score = ' 
                  + convert(varchar,@current) + ') as Score_'
                  + CASE WHEN @current < 0 THEN 'Negative_' 
                              + convert(varchar,ABS(@current)) 
                         ELSE convert(varchar,@current)
                         END
    if @current < @maxScore set @dynSQL = @dynSQL + ', '
    set @current = @current + 1
end

exec(@dynSQL)
​
于 2010-09-16T18:31:10.580 に答える