How to select rows, and nearby rows
This is your existing logic rewritten using an moving max:
WITH dt AS ( SELECT ID, AddedDate, -- check if there's a NULL within a range of +/- 3 rows -- and remember it's ID max(case when AddedDate is null then id end) over (order by id rows between 3 preceding and 3 following) as NullID FROM Items )SELECT *FROM dtwhere id between NullID-3 and NullID+3
Here is one method that uses the windowing clause:
select i.*from (select i.*, count(*) over (order by id rows between 3 preceding and 1 preceding) as cnt_prec, count(*) over (order by id rows between 1 following and 3 following) as cnt_foll, count(addeddate) over (order by id rows between 3 preceding and 1 preceding) as cnt_ad_prec, count(addeddate) over (order by id rows between 1 following and 3 following) as cnt_ad_foll from items ) iwhere cnt_ad_prec <> cnt_prec or cnt_ad_foll <> cnt_foll or addeddate is null;order by id;
This returns all rows that have NULL
in the column or are within three rows of a NULL
.
The need for the comparison to the count is to avoid the edge issues on the smallest and largest ids.
Another way:
SELECT i1.* FROM Items i1, Items i2 WHERE i2.AddedDate IS NULL AND ABS(i1.ID - i2.ID) <= 3
I hope there is index on AddedDate
column.