繁体   English   中英

替代聚合案例语句SQL Server

[英]Alternative to Aggregate Case Statements SQL Server

我创建了一个基于CASE表达式进行聚合的视图。 视图所基于的事务表具有大约9亿行。 我需要根据多个条件汇总值,包括日期和产品代码。 我需要至少对数据进行一次全面扫描,因为我们在没有过滤器的情况下进行了一些聚合,因此我认为使用case语句将允许它只进行1次扫描而不必为每个标准运行查询。

我发现,拥有如此多的聚合案例陈述确实会减慢事情的速度。

这是我的查询只有2列的例子(在真正的查询中可能有50列)

SELECT  [ContactID] AS [ContactID],
        COUNT(DISTINCT CASE
                           WHEN [Category] = 'Dog Food'
                                AND [TransactionDate]
                                BETWEEN DATEADD(MONTH, -12, DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)) AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
                                THEN [TransactionDate]
                           ELSE NULL
                       END
            )       AS [Dog_FoodTx12mth],
        COUNT(DISTINCT CASE
                           WHEN [Category] = 'Cat Food'
                                AND [Lifestage] LIKE 'Kitten%'
                                AND [TransactionDate]
                                BETWEEN DATEADD(MONTH, -3, DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)) AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
                                THEN [TransactionDate]
                           ELSE NULL
                       END
            )       AS [Cat_FoodKittenTx3mth]
FROM    [dbo].[GI_TransactionLineProductContact]
GROUP BY [ContactID];

编辑问题以澄清:

是否有另一种方法,而不是聚合CASE表达式,这可能会更有效,记住我至少要对表格进行一次完整读取? 我认为我的主要问题是不同CASE表达式的所有嵌套循环,每个新的case表达式似乎都会增加相当多的成本。 如果我针对具有2个CASE表达式的相同条件和具有50个CASE表达式的查询执行查询的估计执行计划,则第一个查询显示20%的成本,第二个查询显示80%的批处理成本。

所以我认为这个设计可能不是最有效的,我正在寻找可以使用的潜在替代方法。

谢谢

首先你的查询是错误的。 它会输出错误的输出

其次使用DISTINCT尚不清楚。

尝试我的脚本,如果你没有得到正确的输出,那么你可以放回DISTINCT

SELECT  [ContactID] AS [ContactID],
        sum( CASE
                           WHEN [Category] = 'Dog Food'
                                AND [TransactionDate]
                                BETWEEN DATEADD(MONTH, -12, DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)) AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
                                THEN 1
                           ELSE 0
                       END
            )       AS [Dog_FoodTx12mth],
        SUM(CASE
                           WHEN [Category] = 'Cat Food'
                                AND [Lifestage] LIKE 'Kitten%'
                                AND [TransactionDate]
                                BETWEEN DATEADD(MONTH, -3, DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)) AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
                                THEN 1
                           ELSE 0
                       END
            )       AS [Cat_FoodKittenTx3mth]
FROM    [dbo].[GI_TransactionLineProductContact]
GROUP BY [ContactID];

为什么您的查询可能有误?

select count(*) from
(
select 1 col
union all
select null
)t4

输出返回是2.desire输出= 1.Am我错了/正确吗?

如果您使用DISTINCT然后使用CTE过滤器重复记录使用单个distinct或row_number()over(按类别分区,transactiondate order by transactiondate)rn

通过ContactID + Category + Lifestage +您需要的TransactionDate间隔(例如td_year,td_month,td_day)+您需要的任何其他字段作为标准进行分组会更有效。 然后使用标准聚合,最后使用适合您的任何技术(WITH,临时表,嵌套选择,视图等)从外部选择中按ContactID选择该组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM