我以前从未使用过TSQL,但我决定无论如何都希望在SO data dump中使用它。所以这可能是一个新秀问题。我确实试图寻找答案,但我不知道我正在尝试做什么的技术术语,如果你没有合适的关键词,搜索就会很好。
我的目标是找出有多少问题得分为0,有多少得分为1,有多少得分为2,& c。我可以写一个查询来找出那些个人计数,没问题。不过,我希望能够运行包含循环的查询。以下是我到目前为止所使用的内容:
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]或任何必要的内容来解决所有现有问题。显然,我的问题是我' m抓住循环的每个循环中的计数,然后不对它做任何事情。目前,我得到的结果只是最初设置的@counter
的计数;迭代次数无关紧要。是否可以将结果存储在某处,然后显示为:
+-------+--------------------------------+ | Score | NumberOfQuestionsWithThatScore | +-------+--------------------------------+ | -10 | 111 | +-------+--------------------------------+ | -9 | 0 | +-------+--------------------------------+ | -8 | 248 | +-------+--------------------------------+ | ... | ... | +-------+--------------------------------+
(编辑:任何合理清晰的显示都可以,上表只是一个样本; 编辑2 :修改了表格的设计以清除持续的混乱)
如果是这样,这叫做什么,怎么做?
答案 0 :(得分:6)
实际上你可以一次性完成这件事......
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
从袖带上解决这个问题,而不是现在在数据库前面验证语法。查看“分组依据”以获得更好的主意。
AS @OMG小马指出,这不像你原来的那样。如果你想拥有一个列,你需要使用SELECT和SUM来做到这一点。
答案 1 :(得分: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
答案 2 :(得分: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)