根据条件获取最新行

时间:2020-07-29 11:46:59

标签: sql sql-server sql-server-2012

我有一张桌子material-HERE IS THE FIDDLE

+--------+-----+-------------------+----------------+-----------+          
| ID     | REV | name              | Description    | curr      |
+--------+-----+-------------------+----------------+-----------+
| 211-32 | 001 | Screw 1.0         | Used in MAT 1  | READY     |
| 211-32 | 002 | Screw 2 plus      | can be Used-32 | WITHDRAWN |
| 212-41 | 001 | Bolt H1           | Light solid    | READY     |
| 212-41 | 002 | BOLT H2+Form      | Heavy solid    | READY     |
| 101-24 | 001 | HexHead 1-A       | NOR-1          | READY     |
| 101-24 | 002 | HexHead Spl       | NOR-22         | READY     |
| 423-98 | 001 | Nut Repair spare  | NORM1          | READY     |
| 423-98 | 002 | Nut Repair Part-C | NORM2          | WITHDRAWN |
| 423-98 | 003 | Nut SP-C          | NORM2+NORM1    | NULL      |
| 654-01 | 001 | Bar               | Specific only  | WITHDRAWN |
| 654-01 | 002 | Bar rod-S         | Designed+Spe   | WITHDRAWN |
| 654-01 | 003 | Bar OPG           | Hard spec      | NULL      |
+--------+-----+-------------------+----------------+-----------+

每个ID可以有多个修订版本。我想采用最新版本(即最高001,002,003等)。但是,如果最新修订版将curr作为NULL(字符串)或WITHDRAWN,则我将采用先前的修订版及其对应的值。如果curr甚至是NULLWITHDRAWN,我都必须再次转到先前的版本。如果所有修订都存在相同的问题,那么我们可以忽略它。所以预期的输出是

+--------+-----+------------------+---------------+-------+
| ID     | REV | name             | Description   | curr  |
+--------+-----+------------------+---------------+-------+
| 211-32 | 001 | Screw 1.0        | Used in MAT 1 | READY |
| 212-41 | 002 | BOLT H2+Form     | Heavy solid   | READY |
| 101-24 | 002 | HexHead Spl      | NOR-22        | READY |
| 423-98 | 001 | Nut Repair spare | NORM1         | READY |
+--------+-----+------------------+---------------+-------+

我已经尝试过下面的代码,但是我不确定如何进行以前的修订。

with cte as (
select *,dense_rank() over (partition by id order by rev desc) as DR ,
lead(curr) over (partition by id order by rev desc) LEAD_CURR
from material )
select * from cte where DR = 1 and curr='READY'
union all
select * from cte where LEAD_CURR='READY' and DR=2
union all
select * from cte where LEAD_CURR='READY' and DR=3

1 个答案:

答案 0 :(得分:1)

这听起来像是过滤,然后计算行号:

select m.*
from (select m.*,
             row_number() over (partition by id order by rev desc) as seqnum
      from material m
      where curr is not null and curr not in ( 'WITHDRAWN', 'NULL' ) 
     ) m
where seqnum = 1;

您也可以使用相关子查询来做到这一点:

select m.*
from material m
where m.rev = (select max(m2.rev)
               from material m2
               where m2.id = m.id and
                     curr is not null and curr not in ( 'WITHDRAWN', 'NULL' ) 
              );

Here是db <>小提琴。

注意:将字符串'NULL'存储在列中是非常不传统的,因为它很容易与SQL“ constant” NULL混淆。

此外,您的问题专门提到了'WITHDRAWN'NULL,但没有说明允许使用其他什么值。显然,以上查询中的逻辑可能等效于curr = 'READY',您可以使用它。以上逻辑遵循您对问题的描述。