2011-10-02 83 views
0
CREATE TABLE IntegrationLog (
IntegrationLogID INT IDENTITY(1,1) NOT NULL, 
RecordID INT NOT NULL, 
SyncDate DATETIME NOT NULL, 
Success BIT NOT NULL, 
ErrorMessage VARCHAR(MAX) NULL, 
PreviousError BIT NOT NULL --last sync attempt for record failed for syncdate 
) 

我的目標在這裏,是爲了回報每一位的recordId,尚未之後取得圓滿成功erorrmessage,排除其中對於recorid有一個(成功== 1和PreviousError == 0)發生此錯誤後發生。對於這個記錄,我也想知道是否曾經有過曾經發生過的成功(部分或其他)。或者換句話說,我想查看發生錯誤以來發生的錯誤和記錄,這些錯誤沒有被修復。我也想知道我是否曾經爲特定的記錄獲得過成功。優化 - 選擇在另一個表是否存在記錄/條件-TSQL

這有效,但我很好奇,如果有更好的方法來做到這一點?

SELECT errors.RecordID , 
     errors.errorMessage, 
     CASE WHEN PartialSuccess.RecordID IS NOT NULL THEN 1 
      ELSE NULL 
     END AS Resolved 
FROM (SELECT errors.RecordID , 
        errors.ErrorMessage , 
        MAX(SyncDate) AS SyncDate 
      FROM  dbo.IntegrationLog AS Errors 
      WHERE  errors.Success = 0 
      GROUP BY errors.RecordID , 
        errors.ErrorMessage , 
        errors.ErrorDescription 
     ) AS Errors 
     LEFT JOIN dbo.IntegrationLog AS FullSuccess ON FullSuccess.RecordID = Errors.RecordID 
                   AND FullSuccess.Success = 1 
                   AND FullSuccess.PreviousError = 0 
                   AND FullSuccess.SyncDate > Errors.SyncDate 
     LEFT JOIN (SELECT partialSuccess.RecordID 
        FROM dbo.IntegrationLog AS partialSuccess 
        WHERE partialSuccess.Success = 1 
        GROUP BY partialSuccess.RecordID 
       ) AS PartialSuccess ON Errors.RecordID = PartialSuccess.RecordID 
WHERE FullSuccess.RecordID IS NULL 

我還用幾種不同的方法創建了一個pastebin,用於構建查詢。 http://pastebin.com/FtNv8Tqw 還有其他選擇嗎?

如果有幫助,該項目的背景是我試圖同步自上次成功同步(部分或全部)以來已更新的記錄並記錄嘗試。一批記錄被識別爲同步。每個記錄嘗試都被記錄。如果失敗,根據錯誤可能會嘗試按摩數據並再次嘗試。對於這個'工作',我們收集記錄的時間被用作SyncDate。因此,對於給定的SyncDate,我們可能會有第一次嘗試成功同步的記錄,第一次嘗試放棄的記錄,我們記錄的記錄以及能夠同步等。每次嘗試都會被記錄下來。

它是否會改變任何事情,而不是想知道該recordid是否已成功發生,我希望確定自上次錯誤發生以來是否發生了部分成功。

謝謝!我對這個問題的建議也很受歡迎。

回答

1

您應該可以顯示查詢計劃,查看大部分時間正在用於何處並適當編制索引。

這就是說你可以嘗試的一件事是使用窗口函數ROW_NUMBER而不是MAX。

WITH cte 
    AS (SELECT errors.recordid, 
       errors.errormessage, 
       CASE 
        WHEN partialsuccess.recordid IS NOT NULL THEN 1 
        ELSE NULL 
       END 
        AS resolved, 
       Row_number() OVER (PARTITION BY errors.recordid ORDER BY 
       syncdate 
       DESC) 
        rn 
     FROM integrationlog error 
       LEFT JOIN integrationlog fullsuccess 
        ON fullsuccess.recordid = errors.recordid 
        AND fullsuccess.success = 1 
        AND fullsuccess.previouserror = 0 
        AND fullsuccess.syncdate > errors.syncdate 
       LEFT JOIN (SELECT partialsuccess.recordid 
          FROM dbo.integrationlog AS partialsuccess 
          WHERE partialsuccess.success = 1 
          GROUP BY partialsuccess.recordid) AS partialsuccess 
        ON errors.recordid = partialsuccess.recordid 
     WHERE errors.success = 0) 
SELECT 
    recordid, 
    errormessage, 
     resolved 
FROM cte 
WHERE rn = 1 
相關問題