将多个SUM连接到一个结果中

时间:2014-04-14 06:19:03

标签: sql sql-server sql-server-2008 query-optimization

我有一个表格,用于存储用户的upvote / downvote以获取内容:

DECLARE @Table TABLE
    (
      [ID] INT IDENTITY(1, 1) ,
      [ContentID] INT ,
      [UserID] INT ,
      [IsUpVote] BIT
    )

IsUpVote是上面的位类型。当有upvote时它的值是1,而对于down vote它的值是0。我需要在每个内容的单个查询中选择upvotes和doownvotes的总和:我已经编写了以下查询来执行相同的操作:

SELECT  ContentID ,
        SUM(CASE WHEN [IsUpVote] = 1 THEN 1
                 ELSE 0
            END) AS [UpVotes] ,
        SUM(CASE WHEN [IsUpVote] = 0 THEN 1
                 ELSE 0
            END) AS [DownVotes]
FROM    @Table
GROUP BY ContentID 

输出:

ContentID   UpVotes     DownVotes
----------- ----------- -----------
1           3           1
2           1           2

有没有更好的方法可以明智地编写上述查询性能,或者abover查询是否合适?

以下是填充上表的数据:

DECLARE @Table TABLE
    (
      [ID] INT IDENTITY(1, 1) ,
      [ContentID] INT ,
      [UserID] INT ,
      [IsUpVote] BIT
    )


INSERT  INTO @Table
        ( ContentID ,
          [UserID] ,
          IsUpVote
        )
        SELECT  1 ,
                1 ,
                1
        UNION
        SELECT  1 ,
                2 ,
                1
        UNION
        SELECT  1 ,
                3 ,
                0
        UNION
        SELECT  1 ,
                4 ,
                1
        UNION
        SELECT  2 ,
                1 ,
                1
        UNION
        SELECT  2 ,
                4 ,
                0
        UNION
        SELECT  2 ,
                3 ,
                0 

SELECT  ContentID ,
        SUM(CASE WHEN [IsUpVote] = 1 THEN 1
                 ELSE 0
            END) AS [UpVotes] ,
        SUM(CASE WHEN [IsUpVote] = 0 THEN 1
                 ELSE 0
            END) AS [DownVotes]
FROM    @Table
GROUP BY ContentID 

1 个答案:

答案 0 :(得分:0)

你可能没有比你拥有的更快,这是一次线性扫描。

这是一个可能的替代查询,可能会得到非常快的结果,但没有什么值得吹嘘的:

select [ContentId],
       SUM([IsUpVote]) as [Upvotes],
       SUM(1 - [IsUpVote]) as [Downvotes]
from @Table
Group By ContentId

请注意,如果ContentId上有索引,则运行速度会更快。更好的是,在{ContentId,IsUpVote}上创建一个索引,以便优化器只需要考虑索引的内容。您可以通过其他方式为此付费,因此在执行此操作之前请仔细考虑。 (当您最初插入数据时,您将为此付费。)