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) |