sql - 在数据周期内有条件地增加字段值 - 有没有一种仅使用 SQL 的方法?

标签 sql oracle plsql window-functions

有没有办法根据数据的循环获取条件增量,并将其在查询字段中向前推进?这是针对 Oracle 11G2 的。

我有个人的每月事件数据(40 多年),跟踪成员(member)资格的变化。个人可以加入该服务、无限期保留、退出以及稍后重新加入。这些更改在退出服务时有一个特定的代码。我正在尝试找到一种方法来跟踪每个人的退出/重新加入周期,并增加列值,显示他们使用服务的次数,并关联在此期间的历史记录。

使用分析函数,我可以检测他们的第一次出现、他们何时离开以及他们离开后何时返回。我还没有找到一种方法来使用它来增加一列并将该值向前推进,直到该人的最后。

这不是一个序列,因为每个个体都从“1”开始。对于我尝试过的逻辑/分区组合,行号对我不起作用。我已经尝试在更改代码上使用 CASE 语句进行子查询,然后使用 LAST_VALUE 在外部查询中将这些语句向前推进 - 但我只是找不到一种方法来获取正确的增量或结转它。我只是不明白。

我已经用我开始的核心查询来摆弄这个。
http://sqlfiddle.com/#!4/65d49/1/0

select recno, uniq, 
   row_number() over (PARTITION by uniq 
                      order by sym , mchty ) histrec,
   sym, 
   mchty, 
   lag( mchty, 1, '99')  over ( PARTITION by uniq 
                                  order by sym ) premchty, 
   (case
      when lag( mchty, 1, '99') over ( PARTITION by uniq 
                                       order by sym  ) = '99'
          then 1
      end ) join_svc,
   (case
      when  lag( mchty, 1, '99') over ( PARTITION by uniq 
                                        order by sym  ) = '6'
          then 1
      end ) rejoin_svc,
      svc svc_num
 from demo_history ;
  • RecNo - 源表中的记录号。

    UNIQ - 个人的唯一标识符。

    SYM - 更改日期,字母数字日期字符串,'YYYYMM' - 我在其他代码中处理一些无效的月份。

    MCHTY - 事件更改代码。事件代码可以是“0”到“6”, 其中“6”是“离开服务”指示符。

记录按更改日期排序,然后按更改类型排序。

在示例查询结果中,

  • HISTREC - 单个历史记录的行号

    PREMCHTY - 最近的更改代码(滞后)

    JOIN_SVC - 集合中的第一条记录

    REJOIN_SVC - 离开后的第一条记录

    SVC (或示例中的 SVC_NUM)是我想要生成的 - 我认为应该是“第n次”服务。

如何在个人离开(“6”)后查询/计算/生成 SVC 字段的内容,并为每个新的时间段递增它?

最终,唯一 ID 和递增的 svc 编号组合将用于为个人每次使用服务时创建主记录。

背景:我正在尝试替换 PL/1 过程中遗留下来的大量过程代码和逻辑,但通过将其放入具有多嵌套游标的 PL/SQL 过程中并在跨域之间共享字段值来进行“更新”通过 IN/OUT 参数的一组记录。
数据规模约为500万条记录,约27万个个人ID。我想将个人的历史记录作为一个集合来处理,使用SQL来代替大部分字段转换。如果我的做法是错误的,或者有更好的方法,请告诉我。

最佳答案

您已经接近解决方案了。您只需使用 SUM 作为 rejoin_svc 列的分析函数即可。但这会给你 svc 号码 从0开始,所以加1即可。

select recno,
uniq,
sym,
mchty,
sum(rejoin_svc) over (PARTITION by uniq order by sym) + 1 svc_num,
svc
from
(
  select recno, uniq, 
       sym, 
       mchty, 
       (case
          when  lag( mchty, 1, '99') over ( PARTITION by uniq 
                                            order by sym  ) = '6'
              then 1
              else 0
          end ) rejoin_svc,
        svc
from demo_history
)
order by recno, uniq, svc;

sqlfiddle

关于sql - 在数据周期内有条件地增加字段值 - 有没有一种仅使用 SQL 的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30795812/

相关文章:

sql - 将表变量与 xp_cmdshell 一起使用

java - 让 hibernate 记录 clob 参数

oracle - DBMS_REDEFINITION.start_redef_table 权限不足错误

oracle - ORA-00922 : missing or invalid option while creating PL/SQL procedure

sql - 如何在名称取自另一个表的表上执行 sql 查询

php - 如何在 SQL 中合并两 (3) 个以上的表

mysql - SQL 仅选择列上具有最大值的行

php - mySql 未知列

xml - 具有命名空间的标签的 Extract/extractValue

c# - 如何通过 oracleBulkCopy (ODP.NET) 检查插入的行数