簡體   English   中英

SQL Server-匯總具有多個條件的表中每一行的SUM

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

一些注意事項:

  1. 我可以通過“活動監視器” =>“最近的昂貴查詢”來獲得執行計划。 由於“數量”字段不在索引中,因此SQL正在執行集群鍵查找和排序,該查詢占用了查詢運行時的97%。

  2. 由於服務器上權限不足,我不得不將數據移到另一台服務器上,在這里我可以創建一個具有“金額”字段的索引。 該查詢用600K行運行了大約5秒鍾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM