【问题标题】:Oracle: Rank with condition and keeping historyOracle:按条件排序并保留历史记录
【发布时间】:2020-04-05 14:49:27
【问题描述】:

我有这个示例表:

我需要创建一个排名列,它将根据 is_true=1 对 id 进行排序,这意味着 is_true 从 0 到 1 的每次更改都会使索引增加 1。 类似于以下内容:

我尝试了类似的方法:

select id, customer_id, is_true,  
       rank() over (partition by customer_id order by (case when is_true=1 then id end)) index_rank 
from table

但它不能满足我的需要。

任何帮助将不胜感激。

【问题讨论】:

  • 样本数据最好显示为formatted text。请参阅here,了解有关如何创建漂亮表格的一些提示。

标签: sql oracle window-functions


【解决方案1】:

改进 GMB 提供的查询

select x.*
       ,sum(case when (is_true=1 and lag_val=0) or (lag_val is null) then 1 end) over(partition by customer_id order by id) index_rank
  from (select *
               ,lag(is_true) over(partition by customer_id order by id) lag_val       
          from dbo.t 
        )x

旧查询

select id
       ,customer_id
       ,is_true
       ,dense_rank() over(partition by customer_id order by customer_id,max_grp)
   from(
        select id
               ,customer_id
               ,is_true
               ,max(is_rank) over(partition by customer_id order by id) max_grp
          from (select id,customer_id,is_true
                       ,case when is_true=1 and lag(is_true) over(partition by customer_id order by id)=0 
                              or  lag(is_true) over(partition by customer_id order by id) is null then
                             DENSE_RANK() over(partition by customer_id order by id)
                        end as is_rank
                   from dbo.t
                 )x
      )y

【讨论】:

    【解决方案2】:

    你可以做一个窗口求和:

    select
        t.*,
        1 + sum(is_true) over(partition by cutsomer_id order by id) index_rank
    from mytable t
    

    如果你想允许连续的1s而不增加排名,那么你可以先使用lag()

    select
        t.*,
        1 + sum(case when is_true = 1 and lag_is_true = 0 then 1 else 0 end) 
            over(partition by cutsomer_id order by id) index_rank
    from (
        select 
            t.*,
            lag(is_true) over(partition by cutsomer_id order by id) lag_is_true
        from mytable t
    ) t
    

    【讨论】:

    • 如果您在 is_true 列中有两个连续的 (1),这可能会出现问题?
    • @GeorgeJoseph:是的。我用该案例的解决方案更新了我的答案。
    • 如果它以 is_true=1 开头也可能有问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 2012-10-18
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多