Han*_*_55 6 sql-server query t-sql
我有桌子src。在此表中,每个产品-国家/地区组合可能包含NULL在Country第一行的列中x。
如何为每个产品-国家/地区组合提供行,仅包含“国家/地区”列中包含的SELECT第一行之后的行?对于后面的任何行也很重要,即使它们确实包含在“国家/地区”列中,只要在其之前至少有一行具有真实值即可。xNULLSELECTNULL
预期输出
例如。
SELECT的行,而不是 ID 1 和 2 的行。SELECT的行,而不是 ID 5 的行。| ID | 产品 | 国家 | 时间戳 |
|---|---|---|---|
| 3 | A | 在 | 2022-01-23 14:29:06.830 |
| 4 | A | 无效的 | 2022-01-24 14:29:06.830 |
| 6 | 乙 | CH | 2022-01-23 14:29:06.830 |
| 7 | 乙 | 无效的 | 2022-01-24 14:29:06.830 |
示例表和数据
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')
Run Code Online (Sandbox Code Playgroud)
像这样的东西应该有效。使用 cte 查找每个产品的第一个不为空的 ID,然后连接回原始表。
;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.MinID
Run Code Online (Sandbox Code Playgroud)
| ID | 产品 | 国家 | 时间戳 |
|---|---|---|---|
| 3 | A | 在 | 2022-01-23 14:29:06.830 |
| 4 | A | 无效的 | 2022-01-24 14:29:06.830 |
| 6 | 乙 | CH | 2022-01-23 14:29:06.830 |
| 7 | 乙 | 无效的 | 2022-01-24 14:29:06.830 |
我们可以为每个产品创建一个枚举,并为每个产品、国家/地区创建一个枚举。通过减去这两个数字,我们可以检测到产品何时改变国家/地区。我们将这个构造属性称为 grp。为了处理第一个国家/地区不为空的情况,我们为这些国家/地区的 grp 添加 1。通过过滤掉 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]
Run Code Online (Sandbox Code Playgroud)
| ID | 产品 | 国家 | 时间戳 |
|---|---|---|---|
| 2 | A | 在 | 2022-01-22 14:29:06.830 |
| 3 | A | 在 | 2022-01-23 14:29:06.830 |
| 4 | A | 2022-01-24 14:29:06.830 | |
| 6 | 乙 | CH | 2022-01-23 14:29:06.830 |
| 7 | 乙 | 2022-01-24 14:29:06.830 | |
| 8 | C | CH | 2022-01-24 14:29:06.830 |
| 归档时间: |
|
| 查看次数: |
930 次 |
| 最近记录: |