Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 根据条件分组数据_Sql Server 2008_Tsql_Group By - Fatal编程技术网

Sql server 2008 根据条件分组数据

Sql server 2008 根据条件分组数据,sql-server-2008,tsql,group-by,Sql Server 2008,Tsql,Group By,我将得到一些数据,我需要根据一些条件过滤掉。样本数据: Cust_ID Date Result 1 2013-08-15 On hold 2 2013-08-16 NULL 3 2013-08-18 WIP 1 2013-08-20 Completed 3 2013-08-25 NULL 4 2013-08-28 NULL 4 2013-08-29 NULL 条件: 根据最新日期获取不同的客户ID(即Max(Date)) 如果最新日期的结果为Nu

我将得到一些数据,我需要根据一些条件过滤掉。样本数据:

Cust_ID Date    Result
1   2013-08-15  On hold
2   2013-08-16  NULL
3   2013-08-18  WIP
1   2013-08-20  Completed
3   2013-08-25  NULL
4   2013-08-28  NULL
4   2013-08-29  NULL
条件:

  • 根据最新日期获取不同的客户ID(即Max(Date))
  • 如果最新日期的结果为Null,则获取除Null以外的任何其他结果的最新记录
  • 如果具有相同客户ID的所有记录的结果为空,则根据日期选择最新的记录
  • 所需输出应为:

    Cust_ID Date    Result
    1   2013-08-20  Completed
    2   2013-08-16  NULL    
    3   2013-08-18  WIP
    4   2013-08-29  NULL
    

    请提供建议。

    您可以轻松地使用CTE,注意CTE不是“需要的”(您可以使用子查询),但我认为它清楚地说明了您在做什么

    WITH NonNull AS
    (
       SELECT CustID, MAX(Date) as Date
       FROM tablename
       GROUP BY CustID
       WHERE Result is not null
    ), Others AS
    (
       SELECT CustID, MAX(Date) as Date
       FROM tablename
       GROUP BY CustID
       WHERE CustID NOT IN (SELECT CustID FROM NonNull)
    ), AlltogetherNow -- not really needed but clearer
    (
       SELECT CustID, Date
       FROM NonNull
       UNION ALL
       SELECT CustID, Date
       FROM Others
    )
    SELECT A.CustID, A.Date, J.Results
    FROM AlltogetherNow A
    JOIN tablename J ON A.CustID = J.CustID AND A.Date = J.Date
    

    首先,在每一行上都需要一个
    IS NULL
    指示器:

    MS SQL Server 2008架构设置

    CREATE TABLE dbo.Results
        ([CustID] int, [Date] datetime, [Result] varchar(9))
    GO
    
    INSERT INTO dbo.Results
        ([CustID], [Date], [Result])
    VALUES
        (1, '2013-08-15 00:00:00', 'On Hold'),
        (2, '2013-08-16 00:00:00', NULL),
        (3, '2013-08-18 00:00:00', 'WIP'),
        (1, '2013-08-20 00:00:00', 'Completed'),
        (3, '2013-08-25 00:00:00', NULL),
        (4, '2013-08-28 00:00:00', NULL),
        (4, '2013-08-29 00:00:00', NULL)
    GO
    
    SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
      FROM dbo.Results
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL |
    |--------|-------------------------------|-----------|-----------|
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |
    
    SELECT *,
           ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
           COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
      FROM(
        SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
        FROM dbo.Results
      )X1
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL | _RN | NOTNULLCOUNT |
    |--------|-------------------------------|-----------|-----------|-----|--------------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |   1 |            2 |
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |   2 |            2 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |   1 |            1 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |   1 |            1 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |   2 |            0 |
    
    SELECT CustID,[Date],Result
    FROM(
      SELECT *,
             ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
             COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
        FROM(
          SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
          FROM dbo.Results
        )X1
      )X2
     WHERE _rn = 1 AND SIGN(NotNullCount) = IsNotNull
    
    | CUSTID |                          DATE |    RESULT |
    |--------|-------------------------------|-----------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |
    
    查询1

    CREATE TABLE dbo.Results
        ([CustID] int, [Date] datetime, [Result] varchar(9))
    GO
    
    INSERT INTO dbo.Results
        ([CustID], [Date], [Result])
    VALUES
        (1, '2013-08-15 00:00:00', 'On Hold'),
        (2, '2013-08-16 00:00:00', NULL),
        (3, '2013-08-18 00:00:00', 'WIP'),
        (1, '2013-08-20 00:00:00', 'Completed'),
        (3, '2013-08-25 00:00:00', NULL),
        (4, '2013-08-28 00:00:00', NULL),
        (4, '2013-08-29 00:00:00', NULL)
    GO
    
    SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
      FROM dbo.Results
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL |
    |--------|-------------------------------|-----------|-----------|
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |
    
    SELECT *,
           ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
           COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
      FROM(
        SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
        FROM dbo.Results
      )X1
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL | _RN | NOTNULLCOUNT |
    |--------|-------------------------------|-----------|-----------|-----|--------------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |   1 |            2 |
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |   2 |            2 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |   1 |            1 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |   1 |            1 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |   2 |            0 |
    
    SELECT CustID,[Date],Result
    FROM(
      SELECT *,
             ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
             COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
        FROM(
          SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
          FROM dbo.Results
        )X1
      )X2
     WHERE _rn = 1 AND SIGN(NotNullCount) = IsNotNull
    
    | CUSTID |                          DATE |    RESULT |
    |--------|-------------------------------|-----------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |
    

    CREATE TABLE dbo.Results
        ([CustID] int, [Date] datetime, [Result] varchar(9))
    GO
    
    INSERT INTO dbo.Results
        ([CustID], [Date], [Result])
    VALUES
        (1, '2013-08-15 00:00:00', 'On Hold'),
        (2, '2013-08-16 00:00:00', NULL),
        (3, '2013-08-18 00:00:00', 'WIP'),
        (1, '2013-08-20 00:00:00', 'Completed'),
        (3, '2013-08-25 00:00:00', NULL),
        (4, '2013-08-28 00:00:00', NULL),
        (4, '2013-08-29 00:00:00', NULL)
    GO
    
    SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
      FROM dbo.Results
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL |
    |--------|-------------------------------|-----------|-----------|
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |
    
    SELECT *,
           ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
           COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
      FROM(
        SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
        FROM dbo.Results
      )X1
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL | _RN | NOTNULLCOUNT |
    |--------|-------------------------------|-----------|-----------|-----|--------------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |   1 |            2 |
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |   2 |            2 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |   1 |            1 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |   1 |            1 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |   2 |            0 |
    
    SELECT CustID,[Date],Result
    FROM(
      SELECT *,
             ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
             COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
        FROM(
          SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
          FROM dbo.Results
        )X1
      )X2
     WHERE _rn = 1 AND SIGN(NotNullCount) = IsNotNull
    
    | CUSTID |                          DATE |    RESULT |
    |--------|-------------------------------|-----------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |
    
    然后,您需要为每个客户确定第一个
    NULL
    行和第一个
    notnull
    行。您可以使用
    ROW\u NUMBER()。您还需要知道每个客户是否有任何
    notnull
    行:

    查询2

    CREATE TABLE dbo.Results
        ([CustID] int, [Date] datetime, [Result] varchar(9))
    GO
    
    INSERT INTO dbo.Results
        ([CustID], [Date], [Result])
    VALUES
        (1, '2013-08-15 00:00:00', 'On Hold'),
        (2, '2013-08-16 00:00:00', NULL),
        (3, '2013-08-18 00:00:00', 'WIP'),
        (1, '2013-08-20 00:00:00', 'Completed'),
        (3, '2013-08-25 00:00:00', NULL),
        (4, '2013-08-28 00:00:00', NULL),
        (4, '2013-08-29 00:00:00', NULL)
    GO
    
    SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
      FROM dbo.Results
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL |
    |--------|-------------------------------|-----------|-----------|
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |
    
    SELECT *,
           ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
           COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
      FROM(
        SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
        FROM dbo.Results
      )X1
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL | _RN | NOTNULLCOUNT |
    |--------|-------------------------------|-----------|-----------|-----|--------------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |   1 |            2 |
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |   2 |            2 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |   1 |            1 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |   1 |            1 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |   2 |            0 |
    
    SELECT CustID,[Date],Result
    FROM(
      SELECT *,
             ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
             COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
        FROM(
          SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
          FROM dbo.Results
        )X1
      )X2
     WHERE _rn = 1 AND SIGN(NotNullCount) = IsNotNull
    
    | CUSTID |                          DATE |    RESULT |
    |--------|-------------------------------|-----------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |
    

    CREATE TABLE dbo.Results
        ([CustID] int, [Date] datetime, [Result] varchar(9))
    GO
    
    INSERT INTO dbo.Results
        ([CustID], [Date], [Result])
    VALUES
        (1, '2013-08-15 00:00:00', 'On Hold'),
        (2, '2013-08-16 00:00:00', NULL),
        (3, '2013-08-18 00:00:00', 'WIP'),
        (1, '2013-08-20 00:00:00', 'Completed'),
        (3, '2013-08-25 00:00:00', NULL),
        (4, '2013-08-28 00:00:00', NULL),
        (4, '2013-08-29 00:00:00', NULL)
    GO
    
    SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
      FROM dbo.Results
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL |
    |--------|-------------------------------|-----------|-----------|
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |
    
    SELECT *,
           ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
           COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
      FROM(
        SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
        FROM dbo.Results
      )X1
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL | _RN | NOTNULLCOUNT |
    |--------|-------------------------------|-----------|-----------|-----|--------------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |   1 |            2 |
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |   2 |            2 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |   1 |            1 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |   1 |            1 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |   2 |            0 |
    
    SELECT CustID,[Date],Result
    FROM(
      SELECT *,
             ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
             COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
        FROM(
          SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
          FROM dbo.Results
        )X1
      )X2
     WHERE _rn = 1 AND SIGN(NotNullCount) = IsNotNull
    
    | CUSTID |                          DATE |    RESULT |
    |--------|-------------------------------|-----------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |
    
    最后,您可以使用计算出的行号筛选出第一个
    NOT NULL
    行(如果有),或者第一个
    NULL
    行(如果没有
    NOT NULL
    行):

    查询3

    CREATE TABLE dbo.Results
        ([CustID] int, [Date] datetime, [Result] varchar(9))
    GO
    
    INSERT INTO dbo.Results
        ([CustID], [Date], [Result])
    VALUES
        (1, '2013-08-15 00:00:00', 'On Hold'),
        (2, '2013-08-16 00:00:00', NULL),
        (3, '2013-08-18 00:00:00', 'WIP'),
        (1, '2013-08-20 00:00:00', 'Completed'),
        (3, '2013-08-25 00:00:00', NULL),
        (4, '2013-08-28 00:00:00', NULL),
        (4, '2013-08-29 00:00:00', NULL)
    GO
    
    SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
      FROM dbo.Results
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL |
    |--------|-------------------------------|-----------|-----------|
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |
    
    SELECT *,
           ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
           COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
      FROM(
        SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
        FROM dbo.Results
      )X1
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL | _RN | NOTNULLCOUNT |
    |--------|-------------------------------|-----------|-----------|-----|--------------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |   1 |            2 |
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |   2 |            2 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |   1 |            1 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |   1 |            1 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |   2 |            0 |
    
    SELECT CustID,[Date],Result
    FROM(
      SELECT *,
             ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
             COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
        FROM(
          SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
          FROM dbo.Results
        )X1
      )X2
     WHERE _rn = 1 AND SIGN(NotNullCount) = IsNotNull
    
    | CUSTID |                          DATE |    RESULT |
    |--------|-------------------------------|-----------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |
    

    CREATE TABLE dbo.Results
        ([CustID] int, [Date] datetime, [Result] varchar(9))
    GO
    
    INSERT INTO dbo.Results
        ([CustID], [Date], [Result])
    VALUES
        (1, '2013-08-15 00:00:00', 'On Hold'),
        (2, '2013-08-16 00:00:00', NULL),
        (3, '2013-08-18 00:00:00', 'WIP'),
        (1, '2013-08-20 00:00:00', 'Completed'),
        (3, '2013-08-25 00:00:00', NULL),
        (4, '2013-08-28 00:00:00', NULL),
        (4, '2013-08-29 00:00:00', NULL)
    GO
    
    SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
      FROM dbo.Results
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL |
    |--------|-------------------------------|-----------|-----------|
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |
    
    SELECT *,
           ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
           COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
      FROM(
        SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
        FROM dbo.Results
      )X1
    
    | CUSTID |                          DATE |    RESULT | ISNOTNULL | _RN | NOTNULLCOUNT |
    |--------|-------------------------------|-----------|-----------|-----|--------------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |         1 |   1 |            2 |
    |      1 | August, 15 2013 00:00:00+0000 |   On Hold |         1 |   2 |            2 |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      3 | August, 25 2013 00:00:00+0000 |    (null) |         0 |   1 |            1 |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |         1 |   1 |            1 |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |         0 |   1 |            0 |
    |      4 | August, 28 2013 00:00:00+0000 |    (null) |         0 |   2 |            0 |
    
    SELECT CustID,[Date],Result
    FROM(
      SELECT *,
             ROW_NUMBER()OVER(PARTITION BY CustID,IsNotNull ORDER BY [Date] DESC) _rn,
             COUNT(Result)OVER(PARTITION BY CustID) NotNullCount
        FROM(
          SELECT *,CASE WHEN Result IS NULL THEN 0 ELSE 1 END IsNotNull
          FROM dbo.Results
        )X1
      )X2
     WHERE _rn = 1 AND SIGN(NotNullCount) = IsNotNull
    
    | CUSTID |                          DATE |    RESULT |
    |--------|-------------------------------|-----------|
    |      1 | August, 20 2013 00:00:00+0000 | Completed |
    |      2 | August, 16 2013 00:00:00+0000 |    (null) |
    |      3 | August, 18 2013 00:00:00+0000 |       WIP |
    |      4 | August, 29 2013 00:00:00+0000 |    (null) |