优化 - 选择是否在另一个表-TSQL中存在记录/条件

时间:2011-10-02 04:32:04

标签: sql sql-server sql-server-2005 tsql optimization

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
)

我的目标是返回每个记录,即没有完全成功的erorrmessage,排除在上一次之后发生的记录(成功== 1和PreviousError == 0)的位置错误发生了。对于这个记录,我也想知道是否曾经发生过(部分或其他)成功。

或者换句话说,我希望看到自错误发生以来未修复的错误及其发生的记录。我也想知道我是否曾在特定记录中取得过成功。

这有效,但我很好奇是否有更好的方法来做到这一点?

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,我们可能会在第一次尝试时成功同步的记录,我们在第一次尝试时放弃的记录,我们按摩的记录以及能够同步的记录等。每次尝试都会被记录。

如果不想知道该记录是否有任何成功,它是否会改变任何内容,我希望确定自上次错误发生以来是否已经发生了部分成功。

谢谢!关于我提出这个问题的建议也很受欢迎。

1 个答案:

答案 0 :(得分:1)

您应该显示查询计划,看看大部分时间花在哪里并适当地编制索引。

那说你可以尝试的一件事就是使用Window函数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