Sql-Server

選擇包含 NULL 的前 x 行之後的所有行

  • March 13, 2022

我有桌子src。在此表中,每個 Product-Country 組合可能包含NULLCountry第一x行的列中。

我如何才能SELECT為每個 Product-Country 組合行,僅在 Country 列x中包含的第一行之後的行NULL?任何後面的行也很重要SELECT,即使它們確實包含NULL在 Country 列中,只要在它之前至少有一行具有真實值。

預期產出

例如。

  1. 對於產品 A,我想要ID 3 和 4SELECT的行,而不是 ID 1 和 2 的行。
  2. 對於產品 B,我想要ID 為 6 和 7SELECT的行,但不是 ID 5。

樣本表和數據

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

我們可以為每個產品創建一個列舉,每個產品、國家創建一個。通過減去這兩個數字,我們可以檢測到產品何時更改國家/地區。我們稱這個構造屬性為 grp。為了處理第一個國家不為空的情況,我們為這些添加 1 到 grp。通過過濾掉所有 grp = 0 的行,我們得到了預期的結果:

select ID, Product, Country, [Timestamp]
from (
 select s.*
      , case when country is not null then 1 else 0 end
      + row_number() over (partition by Product order by [Timestamp]) 
      - row_number() over (partition by Product, country order by [Timestamp]) grp
 from dbo.src s
) as T
where grp > 0
order by product, [Timestamp]

小提琴2

引用自:https://dba.stackexchange.com/questions/306913