代码之家  ›  专栏  ›  技术社区  ›  Pops Atula

如何存储TSQL查询结果以便以后显示

  •  2
  • Pops Atula  · 技术社区  · 14 年前

    我以前从来没有用过TSQL,但我决定在SOL中四处看看。 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]或任何必要的方法来解决所有现有的问题)显然,我的问题是在循环的每个循环中获取计数,然后不使用它。目前,我得到的结果只是 @counter 初始设置为;迭代次数不相关。是否可以将结果存储在某个地方,然后显示为:

    +-------+--------------------------------+
    | Score | NumberOfQuestionsWithThatScore |
    +-------+--------------------------------+
    |   -10 |                           111  |
    +-------+--------------------------------+
    |    -9 |                             0  |
    +-------+--------------------------------+
    |    -8 |                           248  |
    +-------+--------------------------------+
    |   ... |                           ...  |
    +-------+--------------------------------+
    

    ( 编辑 :任何合理清晰的显示都可以,上表只是一个样本; 编辑2 :修改了表的设计,以消除持续的混乱)

    如果是这样的话,这叫什么,怎么做?

    3 回复  |  直到 7 年前
        1
  •  6
  •   GrayWizardx    14 年前

    事实上,你可以一次通过…

    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
    

    酸痛是从袖口,而不是在数据库前面现在来验证语法。查找“分组依据”以获得更好的想法。

    正如@omg ponies指出的那样,这并不像你原来那样旋转。如果希望只有一列,则需要使用Select和Sum来完成此操作。

        2
  •  6
  •   OMG Ponies    14 年前

    您列出的输出是一个标准的透视查询,将行转换为列数据:

    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
    
        3
  •  1
  •   Fosco    14 年前

    示例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)
    ​