【问题标题】:ROW_Number with Custom GroupROW_Number 与自定义组
【发布时间】:2020-02-19 10:33:26
【问题描述】:

我正在尝试基于自定义分组创建row_number,但我无法生成它。

以下是我的查询

CREATE TABLE mytbl (wid INT, id INT)
INSERT INTO mytbl Values(1,1),(2,1),(3,0),(4,2),(5,3)

电流输出

wid     id
1        1
2        1
3        0
4        2
5        3

查询

SELECT *, RANK() OVER(PARTITION BY wid, CASE WHEN id = 0 THEN 0 ELSE 1 END ORDER BY ID)
FROM mytbl

我想根据自定义条件对行进行排名,例如如果 ID 为 0,那么我将开始新组,直到我有非 0 ID。

预期输出

wid     id  RN
1        1  1
2        1  1
3        0  1
4        2  2
5        3  2

【问题讨论】:

  • 你是什么意思“直到我有相同的等级。”?不止一个0 的例子会让我们更容易理解大局。还是只是所有 prior 行 +1 上的 0 的数量?
  • @Larnu 我已经更新了。实际上,我想根据 ID 列对行进行排名,如果出现任何 0 值,那么我必须增加它

标签: sql sql-server rank partition row-number


【解决方案1】:

试试这个,

CREATE TABLE #mytbl (wid INT, id INT)
INSERT INTO #mytbl Values(1,1),(2,1),(3,0)
,(4,2),(5,3),(6,0),(7,4),(8,5),(9,6)

;with CTE as
(
select *,ROW_NUMBER()over(order by wid)rn 
from #mytbl where id=0

)
,CTE1 as
(
select max(rn)+1 ExtraRN from CTE
)
select a.* ,isnull(ca.rn,ca1.ExtraRN) from #mytbl a
outer apply(select top 1 * from CTE b 
where a.wid<=b.wid )ca
cross apply(select ExtraRN from CTE1)ca1


drop table #mytbl

这里OUTER APPLYCROSS APPLY 都不会增加cardianility 估计值。它总是只返回一行。

【讨论】:

    【解决方案2】:

    没有太多说明所需的逻辑,我的理解是你想在id = 0 时将Rank 增加1

    select  wid, id, 
            [Rank]  = sum(case when id = 0 then 1 else 0 end) over(order by wid) 
                    + case when id <> 0 then 1 else 0 end
    from    mytbl
    

    【讨论】:

      【解决方案3】:

      在这里猜测,因为我们没有太多澄清,但也许是这样:

      SELECT wid,
             id,
             COUNT(CASE id WHEN 0 THEN 1 END) OVER (ORDER BY wid ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) +1 AS [Rank]
      FROM mytbl ;
      

      【讨论】:

      • @VigneshKumarA 的语法非常具体。首先,您有一个COUNT 的值,其中id 的值为0。但是,由于OVER 子句中的ROWS BETWEEN,仅计算行的之前 行。然后它加 1(否则它将是 0 排名,而不是 1 排名)。
      【解决方案4】:

      如果我理解正确,您可以使用下一种方法。请注意,您需要有一个排序列(我假设这是wid 列):

      声明:

      ;WITH ChangesCTE AS (
          SELECT 
              *,
              CASE WHEN LAG(id) OVER (ORDER BY wid) = 0 THEN 1 ELSE 0 END AS ChangeIndex
          FROM mytbl
      ), GroupsCTE AS (
          SELECT 
              *,
              SUM(ChangeIndex) OVER (ORDER BY wid) AS GroupIndex
          FROM ChangesCTE
      )
      SELECT 
          wid,
          id,
          DENSE_RANK() OVER (ORDER BY GroupIndex) AS Rank
      FROM GroupsCTE
      

      结果:

      wid id  Rank
      1   1   1
      2   1   1
      3   0   1
      4   2   2
      5   3   2
      

      【讨论】:

        猜你喜欢
        • 2018-03-24
        • 1970-01-01
        • 2011-03-10
        • 2014-04-21
        • 2018-09-18
        • 1970-01-01
        • 2012-10-02
        • 1970-01-01
        相关资源
        最近更新 更多