根据条件对结果集进行排序

Rank result set according to condition

我有一个 table,它有 3 列:产品、日期、状态

我想这样排名: 对于按日期排列的每个产品订单,如果 Status = FALSE 则排名为 0,如果为 TRUE,则从 1 开始排名,如果之前的 Status 为 TRUE,则继续按相同的值排名。

在这个有序集合中,如果 FALSE 出现,则分配给它 0,对于同一产品的下一个 TRUE 状态,分配 x+1(这里的 x 是状态 TRUE 的先前排名值)。

希望图片更清楚

试试这个查询,

SELECT  a.Product ,
    a.Date ,
    a.Status ,
    CASE WHEN a.Status = 'FALSE' THEN 0
         ELSE 1
    END [Rank]

FROM ( SELECT 产品 , 日期 , 状态 , ROW_NUMBER() OVER ( PARTITION BY Product ORDER BY DATE, Status ) RNK FROM 表产品 ) 一种 按产品排序,a.RNK

此代码使用不包含 LEAD/LAG 的 SS2008R2 功能。使用更现代版本的 SQL 服务器当然可以有更好的解决方案。

-- Sample data.
declare @Samples as Table ( Product VarChar(10), ProductDate Date,
  ProductStatus Bit, DesiredRank Int );
insert into @Samples values
  ( 'a', '20160525', 0, 0 ), ( 'a', '20160526', 1, 1 ), ( 'a', '20160529', 1, 1 ),
  ( 'a', '20160601', 1, 1 ), ( 'a', '20160603', 0, 0 ), ( 'a', '20160604', 0, 0 ),
  ( 'a', '20160611', 1, 2 ), ( 'a', '20160612', 0, 0 ), ( 'a', '20160613', 1, 3 ),
  ( 'b', '20160521', 1, 1 ), ( 'b', '20160522', 0, 0 ), ( 'b', '20160525', 1, 2 );
select * from @Samples;

-- Query to rank data as requested.
with WithRN as (
  select Product, ProductDate, ProductStatus, DesiredRank,
    Row_Number() over ( partition by Product order by ProductDate ) as RN
    from @Samples
  ),
  RCTE as (
  select *, Cast( ProductStatus as Int ) as C
    from WithRN
    where RN = 1
  union all
  select WRN.*, C + Cast( 1 - R.ProductStatus as Int ) * Cast( WRN.ProductStatus as Int )
    from RCTE as R inner join
      WithRN as WRN on WRN.Product = R.Product and WRN.RN = R.RN + 1 )
  select Product, ProductDate, ProductStatus, DesiredRank,
    C * ProductStatus as CalculatedRank
    from RCTE
    order by Product, ProductDate;

请注意,示例数据是使用 Mark I Eyeball 从图像中提取的。如果 OP 听取了建议 here 它会更容易一些。

提示:使用与数据类型和关键字不匹配的列名可以让事情变得更简单。