首先,您需要IS NULL
在每一行上设置一个指标:
SQL小提琴
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
查询 1:
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 |
然后您需要确定每个客户的第一NULL
行和第一NOT NULL
行。您可以使用该ROW_NUMBER()
功能。您还需要知道每个客户是否有任何NOT NULL
行:
查询 2:
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 |
最后,您可以使用计算的行号过滤掉第一NOT NULL
行(如果有)或第一NULL
行(如果没有行):NOT NULL
查询 3:
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) |