patternsqlMinor
Select all rows after first x rows containing NULLs
Viewed 0 times
afterrowscontainingallfirstselectnulls
Problem
I have table
How can I
Expected Output
For example.
ID
Product
Country
Timestamp
3
A
AT
2022-01-23 14:29:06.830
4
A
NULL
2022-01-24 14:29:06.830
6
B
CH
2022-01-23 14:29:06.830
7
B
NULL
2022-01-24 14:29:06.830
Sample Table and Data
src. In this table, each Product-Country combination might contain NULL in the Country column for the first x rows.How can I
SELECT rows for each Product-Country combination, only rows after the first x rows that contain NULL in the Country column? It's important to also SELECT any latter rows, even if they do contain NULL in the Country column, as long as there was at least one row with a true value, prior to it.Expected Output
For example.
- For product A, I would like to
SELECTrows with ID 3 and 4, but not ID 1 and 2.
- For Product B, I would like to
SELECTrows with ID 6 and 7, but not ID 5.
ID
Product
Country
Timestamp
3
A
AT
2022-01-23 14:29:06.830
4
A
NULL
2022-01-24 14:29:06.830
6
B
CH
2022-01-23 14:29:06.830
7
B
NULL
2022-01-24 14:29:06.830
Sample Table and Data
create table dbo.src
(
ID int not null
,Product varchar(2) not null
,Country varchar(2) null
,[Timestamp] datetime not null
)
insert into dbo.src
(ID,Product, Country, [Timestamp])
values
(1,'A',NULL,'2022-01-21 14:29:06.830')
,(2,'A',NULL,'2022-01-22 14:29:06.830')
,(3,'A','AT','2022-01-23 14:29:06.830')
,(4,'A',NULL,'2022-01-24 14:29:06.830')
,(5,'B',NULL,'2022-01-22 14:29:06.830')
,(6,'B','CH','2022-01-23 14:29:06.830')
,(7,'B',NULL,'2022-01-24 14:29:06.830')Solution
Something like this should work. Use a cte to find the first ID for each product that is not null, then join back to the original table.
ID
Product
Country
Timestamp
3
A
AT
2022-01-23 14:29:06.830
4
A
NULL
2022-01-24 14:29:06.830
6
B
CH
2022-01-23 14:29:06.830
7
B
NULL
2022-01-24 14:29:06.830
Fiddle
;WITH cMinProductId AS (
SELECT Product, MIN(ID) MinID
FROM dbo.src
WHERE Country IS NOT NULL
GROUP BY Product
)
SELECT s.*
FROM dbo.src AS s
INNER JOIN cMinProductId AS mp
ON s.Product = mp.Product
WHERE s.ID >= mp.MinIDID
Product
Country
Timestamp
3
A
AT
2022-01-23 14:29:06.830
4
A
NULL
2022-01-24 14:29:06.830
6
B
CH
2022-01-23 14:29:06.830
7
B
NULL
2022-01-24 14:29:06.830
Fiddle
Code Snippets
;WITH cMinProductId AS (
SELECT Product, MIN(ID) MinID
FROM dbo.src
WHERE Country IS NOT NULL
GROUP BY Product
)
SELECT s.*
FROM dbo.src AS s
INNER JOIN cMinProductId AS mp
ON s.Product = mp.Product
WHERE s.ID >= mp.MinIDContext
StackExchange Database Administrators Q#306913, answer score: 5
Revisions (0)
No revisions yet.