Sql 基于下一行的值的行数

Sql 基于下一行的值的行数,sql,sql-server,ssms,Sql,Sql Server,Ssms,这是表格的一个示例: 基于该表,我需要创建一个查询,该查询的结果如下: 我将为每个ProductID设置一行,N个列的数量以及中断前的返工次数,如果产品中断10次,那么我将看到10列。您可以使用窗口函数计算每行的中断次数。然后只需使用条件聚合: select productid, creationdate, sum(case when statustype = 'rework' and num_breaks = 0 then 1 else 0

这是表格的一个示例:

基于该表,我需要创建一个查询,该查询的结果如下:


我将为每个ProductID设置一行,N个列的数量以及中断前的返工次数,如果产品中断10次,那么我将看到10列。

您可以使用窗口函数计算每行的中断次数。然后只需使用条件聚合:

select productid, creationdate,
       sum(case when statustype = 'rework' and num_breaks = 0
                then 1 else 0
           end) as cnt_before_first_break,
       sum(case when statustype = 'rework' and num_breaks = 1
                then 1 else 0
           end) as cnt_before_second_break
from (select t.*,
             sum(case when stationtype = 'break' then 1 else 0 end) over
                 (partition by productid, creationdate
                  order by status_timestamp
                 ) as num_breaks
      from t
     ) t
group by productid, creationdate;

因为你只需要2个级别的计数,你可以考虑这个查询。< /P>

with cte as (

select '201207' as ProductId, '2019-10-01' as CreationDate, 'Rework' as StationDesc, '2019-09-01' as status_timestamp
    union all 
    select '201207', '2019-10-01', 'Rework', '2019-09-02' 
    union all
    select '201207', '2019-10-01','Rework', '2019-09-03' 
    union all 
    select '201207', '2019-10-01','Break', '2019-09-04' 
    union all
    select '201207', '2019-10-01','Rework',  '2019-09-05' 
    union all 
    select '201207', '2019-10-01','Rework', '2019-09-06' 
    union all
    select '201207', '2019-10-01','Break', '2019-09-07' 
    union all 
    select '201207', '2019-10-01','Rework', '2019-09-08' 
    union all
    select '201207', '2019-10-01','Break', '2019-09-09' 
) 
select 
    ProductId,
    CreationDate,
    sum(case when status_timestamp < d1
        and StationDesc = 'Rework' then 1 else 0 end) as FirstBreak,
    sum(case when status_timestamp between d1 and d2 
        and StationDesc = 'Rework' then 1 else 0 end) as SecondBreak
from cte
cross join
    (select t1.status_timestamp as d1, t2.status_timestamp as d2 from
        (select row_number() over (partition by ProductId,CreationDate order by status_timestamp) as rn
            , status_timestamp from cte where StationDesc = 'Break') as t1
    left join
        (select row_number() over (partition by ProductId,CreationDate order by status_timestamp) as rn
            , status_timestamp from cte where StationDesc = 'Break') as t2 on t2.rn = t1.rn + 1
    where t1.rn < 2) as t3
group by ProductId,
    CreationDate
输出:


此方法的名称为Windows函数?@TheOA。子查询有一个窗口函数。它有over子句。我明白了,我会做研究,我尝试了这个查询,是的,它对ProductID有效,如果ProductID坏了3-4-5次,它只坏了2次。我试图找到一个解决方案,但这对只有2次坏的情况很有帮助,但是,如果您想运行它来分析一个包含其他ProductId的大表,该表会被破坏3…4…5次或更多次,无论如何,这将有助于更接近我要创建的内容