我的样本数据如下所示

drop 
  table if exists #temp
select 
  * into #temp
from 
  (
    values 
      ('id100', 'status1', 1), 
      ('id100', 'status2', 2), 
      ('id100', 'status1', 3), 
      ('id100', 'status0', 4), 
      ('id100', 'status2', 5), 
      ('id100', 'status2', 6), 
      ('id100', 'status1', 7), 
      ('id100', 'status1', 8), 
      ('id100', 'status2', 9), 
      ('id101', 'status1', 10), 
      ('id101', 'status2', 11)
  ) t(id, status, rowNum) 

我需要TSQL for each id返回紧跟在rowNum之前的rowNum,其中Status=‘status1’.我希望返回这个代码的代码

id status rowNum value
id100 status1 1
id100 status2 2 1
id100 status1 3
id100 status0 4
id100 status2 5 3
id100 status2 6 3
id100 status1 7
id100 status1 8
id100 status2 9 8
id101 status1 10
id101 status2 11 10

我试过这个,但不起作用.

SELECT 
  t1.id, 
  t1.status, 
  t1.rowNum, 
  (
    select 
      MIN(t2.rowNum) 
    from 
      #temp t2 
    where 
      t2.id = t1.id 
      and t2.rowNum < t1.rowNum 
      and t1.status = 'status2'
  ) as test 
from 
  #temp t1

推荐答案

您可以在CASE语句中使用子查询来执行此操作:

-你在说什么?

  select *, CASE WHEN status='status2' then (select max(rowNum) from #temp tmp 
    where tmp.rowNum<t.rowNum and tmp.status='status1') end value
  from #temp t
order by rowNum

输出:

id status rowNum value
id100 status1 1 null
id100 status2 2 1
id100 status1 3 null
id100 status0 4 null
id100 status2 5 3
id100 status2 6 3
id100 status1 7 null
id100 status1 8 null
id100 status2 9 8
id101 status1 10 null
id101 status2 11 10

fiddle

您也可以使用last_value()窗口函数或lag()窗口函数来替换子查询:

发帖主题:Re:Колибри0.7.0

 select *, CASE WHEN status='status2' then 
    (last_value(case when status='status1' then rowNum else null end) ignore nulls over(order by rowNum)) end value
  from #temp t
order by rowNum

输出:

id status rowNum value
id100 status1 1 null
id100 status2 2 1
id100 status1 3 null
id100 status0 4 null
id100 status2 5 3
id100 status2 6 3
id100 status1 7 null
id100 status1 8 null
id100 status2 9 8
id101 status1 10 null
id101 status2 11 10

发帖主题:Re:Колибри0.7.0

select *, CASE WHEN status='status2' then 
    (lag(case when status='status1' then rowNum else null end) ignore nulls over(order by rowNum)) end value
  from #temp t
order by rowNum

输出:

id status rowNum value
id100 status1 1 null
id100 status2 2 1
id100 status1 3 null
id100 status0 4 null
id100 status2 5 3
id100 status2 6 3
id100 status1 7 null
id100 status1 8 null
id100 status2 9 8
id101 status1 10 null
id101 status2 11 10

fiddle

Sql相关问答推荐

当编号和版本的唯一状态更改时报告

Oracle SQL中的累计总数

当我们加入两个表时,我们可以省略GROUP BY中的列名吗?

SQL—如何根据2列填写缺失的值

按每天的最大值分组

SQL:如何将相应位置的两个数组中的元素组合在一起

获得第三名或最老的记录

我可以在SQLite3中使用BLOB作为主键吗?

如何找到一个组合的两个列,这是不是在其他表在ORACLE SQL?

PATINDEX中与[A-Z]匹配(U除外)的正则表达式

SQL按组 Select 最小值,当值不存在时为Null

将最近的结束日期与开始日期相匹配

特殊条件计算小计

SQL 语句将一列中的值与另一列中的不同值相加,同时按第三列进行分组?

SQL 将 Varchar 转换为日期

使用对 nvarchar 列的多个 LIKE 操作优化 SQL 查询

SQL获取两个日期范围之间的计数

如何防止 SQL 中的负收入值并将其重新分配到接下来的月份?

postgreSQL 中的循环表

如何刷新在视图之上创建的表