如果条件满足前一行,则取最新行

Take latest row if condition met else previous row

我有一个table说

+--------+-----+-------------+-----------+
| ID     | REV | Description | curr      |
+--------+-----+-------------+-----------+
| 211-32 | 001 | Screw       | READY     |
| 211-32 | 002 | Screw_2     | NULL      |
| 212-41 | 001 | bolt        | READY     |
| 212-41 | 002 | bolt_v2     | READY     |
| 423-98 | 001 | Nut         | WITHDRAWN |
| 423-98 | 002 | Nut_2       | NULL      |
+--------+-----+-------------+-----------+

我想从这里获取最新版本的ID。但是,如果 curr 是“NULL”,那么我必须取前一行,如果前一个 currWITHDRAWN ,我不需要 ID 本身。所以我的预期输出如下

+--------+-----+-------------+-------+
| ID     | REV | Description | curr  |
+--------+-----+-------------+-------+
| 211-32 | 001 | Screw       | READY |
+--------+-----+-------------+-------+
| 212-41 | 002 | BOLT_2      | READY |
+--------+-----+-------------+-------+  

我已经使用 temp table 尝试了以下查询,但它没有给出所有行。

select *,dense_rank() over (partition by id order by rev desc) as DR 
into #material_DN
from material

select * from #material_DN where DR = case when curr='NULL' then 2 else 1 end

Check the fiddle here

试试这个...

select m.* from (
   select id, max(rev) max_rev
   from material
   where ISNULL(curr, '') <> 'NULL'
   group by id
) s
join material m ON
   m.id = s.id and 
   m.rev = s.max_rev
where
   m.curr <> 'WITHDRAWN'

您可以将 ISNULL(curr, '') <> 'NULL' 更改为简单的 curr <> 'NULL' ..我只是想确保您的示例数据类型安全。

试试这个:

WITH DataSource AS
(
    SELECT *
          ,DENSE_RANK() OVER (PARTITION BY ID ORDER BY REV DESC) AS [row_id]
          ,LEAD(curr) OVER (PARTITION BY ID ORDER BY REV ASC) AS [next]
    FROM material
)
SELECT id, rev, description, curr
FROM DataSource
WHERE ([row_id] = 1 AND [curr] = 'READY')
    OR ([row_id] = 2 and [next] = 'NULL' and [curr] <> 'WITHDRAWN')
ORDER BY ID
        ,[Rev]

这是一个使用 window 函数的更简单的版本...

select * from (
    select *, max(case when curr <> 'NULL' then rev end) over (partition by id) max_rev
    from material
) s where
   rev = max_rev and
   curr <> 'WITHDRAWN';

您可以尝试使用 reference 进行以下查询。

;with cte as (
SELECT ID
, Rev
, Description
, curr = MAX(curr) OVER (PARTITION BY c)
, Row_Number() Over(Partition By Id Order by id desc) as SrNo
FROM
(
    SELECT ID, Rev, Description, curr
        ,c = count(curr) OVER (ORDER BY id)
    FROM material
) a
)
Select ID
, Rev
, Description
, curr
from cte where SrNo = 2 order BY id

Live Demo db<>fiddle