在特定状态后返回具有相同ID的行

时间:2017-01-24 10:35:38

标签: sql sql-server-2012

我会尽我所能。当你也理解这个问题时我知道你的帮助:)

我有一个具有不同ApplicationStatus的列,具有相同的ApplicationID。当ApplicationStatus第一次到达'Audit Complete'并且之后有任何活动然后它应该返回那些ApplicationStatuses(即使'Audit Complete'再次出现在'Audit Complete'ApplicationStatus之后。然后当'Audit Complete'没有出现在ApplicationID组中,那么它也不应该返回那些行。

My Table

这就是我要返回的内容(其他列没有任何问题):

            ApplicationID | Application Status
          ----------------|--------------------
               926521     | Submitted to Bank
               926521     | Audit Complete

第一个“审核完成”ApplicationStatus可以出现在ApplicationID组的任何行中。

以下是我尝试过的代码(如果您希望我缩短代码,请告诉我(我只想告诉您我的尝试):

WITH CTE
AS
(
SELECT 
        status.ApplicationID AS [Application ID],
        ROW_NUMBER() OVER(PARTITION BY status.ApplicationID ORDER BY status.ApplicationID) AS [Row Number],
        status.ApplicationStatusMovementID AS [Application Status Movement ID], 
        status.ApplicationStatus AS [Application Status],
        status.Comment, 
        status.CreatedDate AS [Created Date],
        app.BondFacilitator AS [Bond Facilitator],

        CASE 
        WHEN COUNT(*) OVER(PARTITION BY status.ApplicationID) > 3 AND status.ApplicationStatus IN ('Audit Complete') --OR COUNT(*) OVER(PARTITION BY status.ApplicationID) > 3
        THEN 'NO'
        WHEN COUNT(*) OVER(PARTITION BY status.ApplicationID) > 3 AND status.ApplicationStatus NOT IN ('Audit Complete') --OR COUNT(*) OVER(PARTITION BY status.ApplicationID) > 3
        THEN 'FINE'
        ELSE 'FINE'
        END AS [Status]

FROM Import.OobaApplicationStatusMovement AS status

LEFT OUTER JOIN Import.OobaApplication  AS app ON status.ApplicationID = app.ApplicationID

GROUP BY 
        status.ApplicationID,
        ApplicationStatusMovementID, 
        status.ApplicationStatus, 
        Comment, 
        status.CreatedDate,
        BondFacilitator

)
SELECT  [Application ID],
        [Row Number],
        [Application Status Movement ID], 
        [Application Status],
        Comment,
        [Created Date],
        [Bond Facilitator],
        [Status],

        IIF(COUNT(*) OVER(PARTITION BY [Application ID]) > COUNT([Status]) OVER(PARTITION BY [Application ID], [Status]), 'NO', 'YES') AS [Activity After Audit Completed]


FROM (
    SELECT [Application ID],
        [Row Number],
        [Application Status Movement ID], 
        [Application Status],
        Comment,
        [Created Date],
        [Bond Facilitator],
        [Status],

        IIF(COUNT(*) OVER(PARTITION BY [Application ID]) > COUNT([Status]) OVER(PARTITION BY [Application ID], [Status]), 'NO', 'YES') AS [Activity After Audit Completed]


FROM CTE) AS result

WHERE  [Row Number] IN
    (SELECT [Row Number] + i
    FROM CTE
    CROSS JOIN (SELECT 2 AS i UNION ALL SELECT 3 UNION ALL SELECT 15) AS n
WHERE [Application Status] = 'Audit Complete') AND [Activity After Audit Completed] IN ('NO') AND Status IN ('FINE', 'NO')


ORDER BY [Application ID], [Created Date]

1 个答案:

答案 0 :(得分:1)

也许我错过了什么或者没有把你的问题弄好,但我想解决方案非常简单。请查看以下示例。首先,我定义一个带有一些示例记录的表,然后执行select以显示所有状态,其中" Audit Complete"不是最后的状态:

DECLARE @t TABLE (Application_ID int, RowNumber int, ApplStatus nvarchar(50));

INSERT INTO @t VALUES (926521, 1, 'Work in Progress'), (926521, 2, 'Submitted to Bank'), (926521, 3, 'Audit Complete'),
                      (926521, 4, 'Submitted to Bank'), (926521, 5, 'Audit Complete');

INSERT INTO @t VALUES (933633, 1, 'Work in Progress'), (933633, 2, 'Submitted to Bank'), (933633, 3, 'Cancelled'),
                      (933633, 4, 'Submitted to Bank'), (933633, 5, 'Audit Complete');

WITH cteRows AS(
  SELECT Application_ID
        ,ApplStatus
        ,MIN(RowNumber) OVER (PARTITION BY Application_ID, ApplStatus) rnMinStatus
        ,MAX(RowNumber) OVER (PARTITION BY Application_ID) rnMax
    FROM @t
),
cteFiltered AS(
  SELECT *
    FROM cteRows
    WHERE ApplStatus = 'Audit Complete'
      AND rnMinStatus < rnMax
)
SELECT DISTINCT a.Application_ID, a.ApplStatus
  FROM @t AS a
  JOIN cteFiltered AS b ON a.Application_ID = b.Application_ID
  WHERE a.RowNumber > b.rnMinStatus