如果条件满足前一行,则取最新行
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”,那么我必须取前一行,如果前一个 curr
是 WITHDRAWN
,我不需要 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
试试这个...
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
我有一个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”,那么我必须取前一行,如果前一个 curr
是 WITHDRAWN
,我不需要 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
试试这个...
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