![](/img/trans.png)
[英]How do you sum each row using multiple columns with SQL without it aggregating data?
[英]SQL Server - Aggregating a SUM for each row in a table with multiple conditions
我正在嘗試模擬我在SQL中經常在excel中做的事情,但是我必須做錯什么,因為它將服務器CPU固定為100。
我專門想做的是根據特定條件匯總表中每一行的總和。 查詢如下
SELECT custno,count(custno) as countUse into ##AllTransferMembers
FROM [OLBRET_COPY].[dbo].[ActivityLogs]
where ActivityCode in ('11020','11045','11053')
and DateTime >= '2018-12-20' and DateTime < '2018-12-26' --and ErrorCode in ('')
group by custno
select d.custno, ActivityCode, d.Amount, d.DateTime, a.countUse, MobileDeviceMACId,ErrorMessage
,( select SUM(activitylogs.amount) from [OLBRET_COPY].[dbo].[ActivityLogs] where ActivityLogs.DateTime >= (d.DateTime-2) and ActivityLogs.DateTime <= d.DateTime and ActivityLogs.CustNo = d.CustNo and ActivityLogs.ErrorMessage = '')
FROM [OLBRET_COPY].[dbo].[ActivityLogs] d
inner join ##AllTransferMembers a on d.CustNo = a.CustNo
where ActivityCode in ('11020','11045','11053')
and DateTime >= '2018-12-20' and DateTime < '2019-01-01' --and ErrorCode in ('')
order by CustNo,DateTime
drop table ##AllTransferMembers
問題應該出在子查詢總和聚合上,因為查詢的另一部分經常在不同的設置下運行而沒有任何問題。
(select
SUM(activitylogs.amount)
from [OLBRET_COPY].[dbo].[ActivityLogs]
where ActivityLogs.DateTime >= (d.DateTime-2) and ActivityLogs.DateTime <= d.DateTime
and ActivityLogs.CustNo = d.CustNo
and ActivityLogs.ErrorMessage = '')
我將不勝感激,因為有人解釋了正在發生的事情導致了巨大的效率低下,以及是否有任何方法可以更好地解決該問題。 不幸的是,我無權執行計划。
干杯,
克里斯
首先...我不明白為什么您要為此使用全局臨時表。 您似乎存儲了太多重復項。 無論如何,您都應該創建一個像這樣的索引:
CREATE INDEX IX_AllTransferMembers ON ##AllTransferMembers (CustNo)
無論如何,您都可以使用CTE對子查詢執行相同的操作:
WITH tmp_AllTransferMembers AS (
SELECT custno,count(custno) as countUse
FROM [OLBRET_COPY].[dbo].[ActivityLogs]
where ActivityCode in ('11020','11045','11053')
and DateTime >= '2018-12-20' and DateTime < '2018-12-26'
group by custno)
SELECT d.custno, ActivityCode, d.Amount, d.DateTime,
a.countUse, MobileDeviceMACId,ErrorMessage
,( select SUM(activitylogs.amount)
from [OLBRET_COPY].[dbo].[ActivityLogs]
where ActivityLogs.DateTime >= (d.DateTime-2)
and ActivityLogs.DateTime <= d.DateTime
and ActivityLogs.CustNo = d.CustNo
and ActivityLogs.ErrorMessage = '')
FROM [OLBRET_COPY].[dbo].[ActivityLogs] d
inner join tmp_AllTransferMembers a on d.CustNo = a.CustNo
where d.ActivityCode in ('11020','11045','11053')
and d.DateTime >= '2018-12-20'
and d.DateTime < '2019-01-01' --and ErrorCode in ('')
order by d.CustNo,d.DateTime
您必須確保在ActivityLogs(CustNo,ErrorMessage,DateTime)上有一個索引,正如您所述,無法看到計划並重現計划,因此,要確保其能更好地工作並不容易...
此外,在代碼之前,您可以使用下面的兩行添加內容,以顯示有關花費時間的一些詳細信息。 因為它是一個表,所以它並不容易,但可能會給您一些線索(運行查詢后,請參閱“消息”選項卡上的詳細信息):
SET STATISTICS TIME ON;
SET STATISTICS IO ON;
在大家的幫助下,使用谷歌搜索功能,這是我最后的查詢:
create index [ix_ActLogstmp] on [dbo].[allDataTodorov]
(CustNo, ErrorMessage,DateTime) include (Amount);
With tmp_AllTransferMembers as (
Select
custno,
count(custno) as countUse
from [SegmentationDatamart].[dbo].[allDataTodorov]
where ActivityCode in ('11020','11045','11053')
and [DateTime] >= '2018-08-01' and DateTime < '2018-12-26'
group by custno)
select
d.custno,
ActivityCode,
d.Amount,
d.DateTime,
a.countUse,
MobileDeviceMACId,
ErrorMessage,
( select SUM([allDataTodorov].amount)
from [SegmentationDatamart].[dbo].[allDataTodorov]
where [allDataTodorov].DateTime >= (d.DateTime-2)
and [allDataTodorov].DateTime <= d.DateTime
and [allDataTodorov].CustNo = d.CustNo
and [allDataTodorov].ErrorMessage is null) as [SUM_]
FROM [SegmentationDatamart].[dbo].[allDataTodorov] d
inner join tmp_AllTransferMembers a on d.CustNo = a.CustNo
where d.ActivityCode in ('11010','11011','11020','11045','11053')
and d.DateTime >= '2018-08-01'
and d.DateTime < '2018-12-26'
order by d.CustNo,d.DateTime
drop index [ix_ActLogstmp]
一些注意事項:
我可以通過“活動監視器” =>“最近的昂貴查詢”來獲得執行計划。 由於“數量”字段不在索引中,因此SQL正在執行集群鍵查找和排序,該查詢占用了查詢運行時的97%。
由於服務器上權限不足,我不得不將數據移到另一台服務器上,在這里我可以創建一個具有“金額”字段的索引。 該查詢用600K行運行了大約5秒鍾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.