聚合SQL SELECT语句中的重复情况

时间:2015-04-13 20:44:14

标签: sql sql-server sql-server-2008 case

我正在尝试降低我经常使用的查询的成本和大小,它看起来过于重复而不是最有效的处理方式。

简化表示如下:

SELECT [Year],
       [Month],
       COUNT(CASE WHEN Type = 'Quotation' THEN clientID ELSE NULL END),
       COUNT(CASE WHEN Type = 'Purchase' THEN ClientID ELSE NULL END),
       SUM(CASE WHEN Type = 'Purchase' THEN Cost ELSE NULL END)
       ...           
FROM dbo.Example
GROUP BY [Year],[Month]

我认为我必须能够在尺寸和成本方面削减CASE WHEN ... THEN ELSE NULL END。有什么建议吗?

我正在使用SQL Server 2008 R2,谢谢。

4 个答案:

答案 0 :(得分:0)

按类型制作视图怎么样? (报价,购买等)。通过这种方式,您可以按视图优化视图并进行连接查询以获得所需内容。

答案 1 :(得分:0)

我认为这是“旋转”表格的推荐方法。

查看Microsoft的这篇文章 - > https://support.microsoft.com/en-us/kb/175574

可能费用在'类型'列中,也许你可以索引 - > How to create an index for a string column in sql?

答案 2 :(得分:0)

呃,有什么问题:

SELECT [Year],
       [Month],
       [Type],
       COUNT(ClientID) "Count",
       SUM(Cost) "TotalCost",
       ...           
FROM dbo.Example
GROUP BY [Year],[Month],[Type]

你这样做的方法是对它进行去标准化。这就是性能如此糟糕的原因。当然,您在SUM(Cost)时生成Type = 'Quotation',而您可能不需要,但添加通常不会影响查询效果。

是否有某些原因必须每个[Year],[Month]只有一条记录?

答案 3 :(得分:0)

当你有一些复杂的东西,有很多条件聚合时,根据我的经验,如果你以逐步的方式构建它,它会更快更清晰。也就是说,拥有一个具有所需数据结构的表变量,并使用单个查询向其添加记录,避免使用CASE语句,并且(希望)根据索引列进行记录选择。

所以,如果你有一个名为@TypeTotals的表变量,你可以这样做(使用简化的例子):

 INSERT INTO @TypeTotals
    SELECT [Year],
           [Month],
           [Type],
           COUNT(ClientID),
           Null,
           Null
    FROM   dbo.Example
    WHERE  [Type] = 'Quotation'
    GROUP BY
           [Year], [Month]

 INSERT INTO @TypeTotals
    SELECT [Year],
           [Month],
           [Type],
           Null,
           COUNT(ClientID),
           SUM(Cost)
    FROM   dbo.Example
    WHERE  [Type] = 'Purchase'
    GROUP BY
           [Year], [Month]

... etc ...

然后,您可以总结@TypeTotals的内容。

速度的关键是避免那些CASE语句(正如你已经想到的那样)并使用你可以使用的索引。

并进行实验。如果可以,请使用Profiler,因为执行计划并不总是代表您真正获得的速度。