在数据周期内有条件地增加字段值 - 有没有办法只 SQL?
Incrementing a field value, conditionally, over data cycles - is there a way w/ just SQL?
有没有办法根据数据的循环获取条件增量,并在查询字段中继续使用?这是针对 Oracle,11G2。
我每月有 activity 个人数据(40 岁以上),跟踪会员资格的变化。个人可以加入该服务,无限期保留,退出并稍后重新加入。这些更改在离开服务时有一个特定的代码。我正在尝试找到一种方法来跟踪每个人的这些退出/重新加入周期,并增加一个列值,显示他们在服务中的次数,并关联该期间的历史记录。
使用分析函数,我可以检测到它们的首次出现、离开的时间以及离开后返回的时间。我还没有想出一种方法来使用它来增加一个列并将该值向前传递到该个人的最后。
这不是一个序列,因为每个个体都是从“1”开始的。对于我尝试过的 logic/partition 组合,行号对我不起作用。我已经尝试在更改代码上使用 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
- 来自来源 table 的记录编号。
UNIQ
- 个人的唯一标识符。
SYM
- 更改日期,字母数字日期字符串,'YYYYMM' -
我在其他代码中处理一些无效月份。
MCHTY
- activity 更改代码。 Activity 代码可以是'0'到'6',
'6' 是 "leaves the service" 指标。
记录按更改日期排序,然后按更改类型排序。
示例查询结果中,
HISTREC
- 单个历史记录的行号
PREMCHTY
- 最近更改代码(滞后)
JOIN_SVC
- 集合中的第一条记录
REJOIN_SVC
- 离开后的第一条记录
SVC
(或示例中的 SVC_NUM
)是我要生成的 -
"nth" 我认为应该的服务时间。
如何获取 query/calculate/generate SVC 字段的内容,在每个新的时间段内,在个人离开后 ('6') 增加它?
最终,唯一 ID 和递增的 svc 编号组合将用于为个人每次使用服务创建主记录。
背景:我试图替换 PL/1 程序日遗留下来的大量程序代码和逻辑,但是 "updated" 将其放入 PL/SQL 程序中嵌套游标,并通过 IN/OUT 参数在一组记录中共享字段值。
数据量约为 500 万条记录,约 27 万个个人 ID。我想将个人的历史记录作为一个集合来处理,使用 SQL 来替换大部分字段转换。如果我处理这个问题有误,或者有更好的方法,请告诉我。
您已接近解决方案。您只需要在 rejoin_svc 列上使用 SUM 作为分析函数。但这会给你 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;
递归求解:
with t as (
select recno, uniq, sym, mchty, svc,
row_number() over (partition by uniq order by sym, recno) rn
from demo_history),
u (recno, uniq, sym, mchty, rn, svc, new_svc) as (
select recno, uniq, sym, mchty, rn, svc, 1 new_svc from t where rn = 1
union all
select t.recno, t.uniq, t.sym, t.mchty, t.rn, t.svc,
case when u.mchty= '6' then u.new_svc+1 else u.new_svc end
from t join u on t.uniq = u.uniq and t.rn = u.rn+1 )
select recno, uniq, sym, mchty, rn, svc, new_svc
from u order by uniq, recno
用户@EatÅPeach 给出的答案可能是您应该在这里使用的答案,它很快并且适合您的需求。
但还有其他可能性值得一提并回答您的问题:有没有办法根据数据周期获得条件增量,
并在查询字段中进行? - recursive CTE 在 Oracle 11g 中引入。
主要部分是子查询 u
联合每个 uniq
的第一行并使用 row_number 循环下一行。对于每一行,我正在检查 mchty
的先前值是否为 '6'
,如果是 - 递增 new_svc
.
有没有办法根据数据的循环获取条件增量,并在查询字段中继续使用?这是针对 Oracle,11G2。
我每月有 activity 个人数据(40 岁以上),跟踪会员资格的变化。个人可以加入该服务,无限期保留,退出并稍后重新加入。这些更改在离开服务时有一个特定的代码。我正在尝试找到一种方法来跟踪每个人的这些退出/重新加入周期,并增加一个列值,显示他们在服务中的次数,并关联该期间的历史记录。
使用分析函数,我可以检测到它们的首次出现、离开的时间以及离开后返回的时间。我还没有想出一种方法来使用它来增加一个列并将该值向前传递到该个人的最后。
这不是一个序列,因为每个个体都是从“1”开始的。对于我尝试过的 logic/partition 组合,行号对我不起作用。我已经尝试在更改代码上使用 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
- 来自来源 table 的记录编号。UNIQ
- 个人的唯一标识符。SYM
- 更改日期,字母数字日期字符串,'YYYYMM' - 我在其他代码中处理一些无效月份。MCHTY
- activity 更改代码。 Activity 代码可以是'0'到'6', '6' 是 "leaves the service" 指标。
记录按更改日期排序,然后按更改类型排序。
示例查询结果中,
HISTREC
- 单个历史记录的行号PREMCHTY
- 最近更改代码(滞后)JOIN_SVC
- 集合中的第一条记录REJOIN_SVC
- 离开后的第一条记录SVC
(或示例中的SVC_NUM
)是我要生成的 - "nth" 我认为应该的服务时间。
如何获取 query/calculate/generate SVC 字段的内容,在每个新的时间段内,在个人离开后 ('6') 增加它?
最终,唯一 ID 和递增的 svc 编号组合将用于为个人每次使用服务创建主记录。
背景:我试图替换 PL/1 程序日遗留下来的大量程序代码和逻辑,但是 "updated" 将其放入 PL/SQL 程序中嵌套游标,并通过 IN/OUT 参数在一组记录中共享字段值。
数据量约为 500 万条记录,约 27 万个个人 ID。我想将个人的历史记录作为一个集合来处理,使用 SQL 来替换大部分字段转换。如果我处理这个问题有误,或者有更好的方法,请告诉我。
您已接近解决方案。您只需要在 rejoin_svc 列上使用 SUM 作为分析函数。但这会给你 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;
递归求解:
with t as (
select recno, uniq, sym, mchty, svc,
row_number() over (partition by uniq order by sym, recno) rn
from demo_history),
u (recno, uniq, sym, mchty, rn, svc, new_svc) as (
select recno, uniq, sym, mchty, rn, svc, 1 new_svc from t where rn = 1
union all
select t.recno, t.uniq, t.sym, t.mchty, t.rn, t.svc,
case when u.mchty= '6' then u.new_svc+1 else u.new_svc end
from t join u on t.uniq = u.uniq and t.rn = u.rn+1 )
select recno, uniq, sym, mchty, rn, svc, new_svc
from u order by uniq, recno
用户@EatÅPeach 给出的答案可能是您应该在这里使用的答案,它很快并且适合您的需求。
但还有其他可能性值得一提并回答您的问题:有没有办法根据数据周期获得条件增量, 并在查询字段中进行? - recursive CTE 在 Oracle 11g 中引入。
主要部分是子查询 u
联合每个 uniq
的第一行并使用 row_number 循环下一行。对于每一行,我正在检查 mchty
的先前值是否为 '6'
,如果是 - 递增 new_svc
.