【问题标题】:Oracle - split table in indexed blocksOracle - 索引块中的拆分表
【发布时间】:2017-09-22 18:24:34
【问题描述】:

我必须处理 Oracle 中的一个小问题...我有一个包含 2 列的表,第一列包含日期,第二列包含导入。 “导入列”可以同时具有 NULL 或非 NULL 值。 我想要做的是按日期列排序(这很容易:)),然后在“导入列”中将表拆分为连续的 NULL 或非 NULL 值块,添加第三列,该列对块进行编号。 示例:

Date        Import
01/01/2017  99.12
01/02/2017  18.19
01/03/2017  22.92
01/04/2017  28.10
01/05/2017  
01/06/2017  
01/07/2017  
01/08/2017  33.78
01/09/2017  20.30
01/10/2017  12.33
01/11/2017  
01/12/2017  1.68

这个表应该变成

Date        Import  Block
01/01/2017  99.12   1
01/02/2017  18.19   1
01/03/2017  22.92   1
01/04/2017  28.10   1
01/05/2017          2
01/06/2017          2
01/07/2017          2
01/08/2017  33.78   3
01/09/2017  20.30   3
01/10/2017  12.33   3
01/11/2017          4
01/12/2017  1.68    5

【问题讨论】:

    标签: oracle


    【解决方案1】:

    您可以像这样使用分析函数:

    select d, import, sum(state_change) over (order by d) as block
      from
    (
      select d, import, import_state,
             case when import_state = lag(import_state) over (order by d, import) 
                  then 0 else 1 end state_change
        from
      (
        select d, import, case when import is not null then 1 else 0 end as import_state
          from t
      )
    );
    

    (注意我将您的 DATE 列重命名为 D,因为 DATE 是保留字)。

    分解,从最里面的查询开始:

    select d, import, case when import is not null then 1 else 0 end as import_state
      from t
    

    这会添加一个列import_state,当import 不为空时为1,如果为空,则为0。这会创建“块”,但它们的编号为 1,0,1,0,... 而不是 1,2,3,4,...

    下一部分将每个import_state 与前一行中的进行比较,以检查更改。 state_change 列在发生更改时为 1,否则为 0 - 所以现在每个“块”的第一行为 1,重置为 0。

    然后,外部部分只是简单地将 state_change 值累加求和以给出所需的结果。

    可能有更简单的解决方案!

    【讨论】:

      猜你喜欢
      • 2016-09-01
      • 2020-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      • 2012-06-06
      • 1970-01-01
      相关资源
      最近更新 更多