2015-08-14 56 views
-1

我想实现一个正在运行的演绎总计,但是当我有一个零行时会出现问题。我正在使用SQL Server 2012.CTE和滞后查询

这是我的一批当前结果。

SuppressionDescription SuppressionPriority SuppressionPriorityOrder TotalRecords RecordsLost RunningTotal 
Deceased_Bln 1 1 1376 2 1374 
Pivotal Postcode Exclusions 9 2 1376 0 1374 
Pivotal 3 Month Decline 11 3 1376 24 1352 
Postcode exclusions (Complaints) 12 4 1376 0 1352 
Gone Away (from Barcode on returned mail) 15 5 1376 30 1346 
Pivotal prospects with a Do Not Mail flag 16 6 1376 234 1112 
Email Suppression File 17 7 1376 7 1135 
Opt outs & undeliverables from SMS system 18 8 1376 7 1362 
Generic Phone Number Suppression 19 9 1376 245 1124 
Exclude if not MR, MRS, MISS, MS, NULL 23 10 1376 0 1131 
Total Prospects 9999 11 1376 0 1376 

用我的查询,前两行计算。总共减少1,376个2叶1,374,第二行没有RecordsLost,因此RunningTotal保持不变。到现在为止还挺好。

但是因为第2行有一个0计数,它意味着第3行(虽然它的记录损失为24)不同步。

我试着添加各种case语句,尝试获取不同场景的总数,但它永远不会工作。

这里是我的发言:

;WITH CTE AS (SELECT  ID, SuppressionTypeID, ContactMethodType, SupplierName, SuppressionDescription 
        ,   SuppressionCount, TotalRecords, RecordsLost, SuppressionPriority, SuppressionPriorityOrder 
        ,   CASE WHEN SuppressionPriority = 9999 
            THEN TotalRecords 
            ELSE TotalRecords - RecordsLost END AS RowDiff 
        ,   CASE WHEN RecordsLost = 0 
            THEN LAG(RecordsLost, 1) OVER (PARTITION BY SupplierName, ContactMethodType ORDER BY SuppressionPriorityOrder) 
            ELSE RecordsLost END AS RecordsLostRoll 
        FROM  #tmpSup 
        WHERE  SupplierName  = 'Freeman Grattan Holdings' 
        AND   ContactMethodType = 'A' 
        ) 
    SELECT  SuppressionTypeID, ContactMethodType, SupplierName, SuppressionDescription 
    ,   SuppressionPriority, SuppressionPriorityOrder 
    ,   TotalRecords 
    ,   RecordsLost 
    ,   CASE WHEN SuppressionPriorityOrder = 1 
        THEN RowDiff 
        ELSE (LAG(RowDiff, 1, RowDiff) 
           OVER (PARTITION BY SupplierName, ContactMethodType ORDER BY SuppressionPriorityOrder)) - RecordsLost 
        END AS RunningTotal 
    FROM  CTE 
    ORDER BY SupplierName 
    ,   ContactMethodType 
    ,   SuppressionPriority 

我想看到的RunningTotal为: 1376(用于总前景)

任何建议和提前感谢。

+0

的总和,你可以创建一个[SQL fiidle(HTTP:// sqlfiddle.com/#!6/5d88f/6)与我们的模式? –

回答

0

您可以使用 '窗框' 的窗函数来实现这一目标:

SELECT 
    SuppressionPriorityOrder, 
    TotalRecords, 
    RecordsLost, 
    TotalRecords - SUM(RecordsLost) OVER 
     (
     PARTITION BY SupplierName, ContactMethodType 
     ORDER BY SuppressionPriorityOrder ROWS UNBOUNDED PRECEDING -- this tells the SUM() to add up all preceding records (including the current row) 
    ) RunningTotal 
FROM 
    (
     SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 1 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 2 AS RecordsLost UNION ALL 
     SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 2 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 0 AS RecordsLost UNION ALL 
     SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 3 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 24 AS RecordsLost UNION ALL 
     SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 4 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 0 AS RecordsLost UNION ALL 
     SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 5 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 30 AS RecordsLost 
    ) x 

参考:link

+0

AHiggins你是一个传奇:) – Raymondo

0

我尝试模拟我最好的数据。让我知道如果你需要在sqlFiddle一些变化

SQL FIDDLE DEMO

我用另一个CTE来计算丢失的记录

WITH 
    LOST AS (
     SELECT 
      SuppressionPriorityOrder, 
      (SELECT SUM(RecordsLost) 
      FROM tmpSup T2 
      WHERE T2.SuppressionPriorityOrder <= T1.SuppressionPriorityOrder) as TotalLost 
     FROM tmpSup T1 
    ) 
SELECT 
    T.*, 
    L.TotalLost, 
    CASE WHEN SuppressionPriority = 9999 
     THEN T.TotalRecords 
     ELSE (T.TotalRecords - L.TotalLost) END AS RunningTotal 
FROM 
    tmpSup T INNER JOIN 
    LOST L ON T.SuppressionPriorityOrder = L.SuppressionPriorityOrder 
+0

非常感谢。首先,星期一,我会试一试你的代码片段 – Raymondo