【问题标题】:Optimize - Select whether record/condition exists in another table -TSQL优化 - 选择另一个表中是否存在记录/条件 -TSQL
【发布时间】:2011-10-02 19:43:27
【问题描述】:
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
)

我在这里的目标是返回每个没有完全成功的记录 ID、错误消息,排除记录在最后一次之后发生的位置(Success == 1 和 PreviousError == 0)发生错误。对于这个rec​​ordid,我还想知道是否曾经发生过成功(部分或其他)。

或者换句话说,我想查看错误以及它们发生的记录自错误发生以来尚未修复。我还想知道我是否曾经为特定的 recordid 取得过成功。

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

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 是否发生任何成功,而是想确定自上次发生错误以来是否发生了部分成功,它会改变什么吗?

谢谢!也欢迎对我的问题提出建议。

【问题讨论】:

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


    【解决方案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 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 2020-10-08
      • 2023-04-07
      • 2015-08-27
      • 1970-01-01
      • 2018-05-30
      相关资源
      最近更新 更多