我创建了一个基于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%的批量成本。
所以我认为这个设计可能不是最有效的,我正在寻找可以使用的潜在替代方法。
由于
答案 0 :(得分:0)
首先你的查询是错误的。 它会给出错误的输出
其次使用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 output = 1.Am我错了/正确吗?
如果您使用DISTINCT然后使用CTE过滤器重复记录使用单个distinct或row_number()over(按类别分区,按事务日期的transactiondate顺序)rn
答案 1 :(得分:0)
通过ContactID + Category + Lifestage +您需要的TransactionDate间隔(例如td_year,td_month,td_day)+您需要的任何其他字段作为条件进行分组更有效。然后使用标准聚合,最后使用适合您的外部选择(Contact,临时表,嵌套选择,视图......),通过ContactID从ContactID中选择该组。