[英]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.