[英]Replicating SAS DO loop in Oracle PL/SQL
我正在尝试将 DO 循环从 SAS 复制到 Oracle PL/SQL。 基本上,这个 DO 循环遍历表并为单个员工创建多行。 我对 PL/SQL 中的循环不是很熟悉,因此感谢您提供任何帮助。 除了创建多个表然后组合它们之外,我想不出任何方法来重新创建它。 我会在最后解释更多关于我的想法; 现在,请查看数据示例以及 SAS DO 循环正在执行的操作。
HIST_EMPLOYEE 表:
+----------+----------+--------+
| EMPLOYEE | START_YR | END_YR |
+----------+----------+--------+
| JOHN | 2013 | 2014 |
| WILL | 2012 | 2016 |
| MARK | 2012 | 2012 |
+----------+----------+--------+
SAS 中的 DO 循环:
DATA HIST_EMPLOYEE_NEW;
SET HIST_EMPLOYEE;
DO YR = START_YR TO END_YR;
OUTPUT;
END;
RUN;
输出:
+----------+----------+--------+------+
| EMPLOYEE | START_YR | END_YR | YR |
+----------+----------+--------+------+
| JOHN | 2013 | 2014 | 2013 |
| JOHN | 2013 | 2014 | 2014 |
| WILL | 2012 | 2016 | 2012 |
| WILL | 2012 | 2016 | 2013 |
| WILL | 2012 | 2016 | 2014 |
| WILL | 2012 | 2016 | 2015 |
| WILL | 2012 | 2016 | 2016 |
| MARK | 2012 | 2012 | 2012 |
+----------+----------+--------+------+
我解决这个问题的方法(这在任何方面都没有效率)是创建在END_YR < START_YR + i
上过滤的表,其中i is from 0 to 10
,然后创建YR
列,然后组合所有表。 我可以进一步讨论这个,但我已经觉得这是做事的糟糕方式。
只需制作一张 YR 值从最小值到最大值不等的表格,然后加入该表格。
所以像:
with years as (
select 2012 + rownum - 1 as YR
from dual
connect by rownum < (2016 - 2012)
)
select a.*,b.YR
from HIST_EMPLOYEE a
inner join years b
on a.start_yr <= b.yr and b.yr <= a.end_yr
;
只需更改下限 (2012) 和上限 (2016) 即可更改您想要生成的年数。
看到这个问题: 如何在 Oracle 中填充日历表?
这是一种方法。 “with”子句称为公共表表达式 (CTE),它只是为每个条目设置具有唯一 id 的测试数据。
查询使用 CONNECT BY,可以将其视为返回的每一行的循环机制。 它带有一个名为“level”的变量,每次迭代都会增加一次(从 1 开始)。 定义每行“循环”多少次是表达式 (end_yr-start_yr+1)。 对于 JOHN,我们需要循环 2 次,因为我们需要 2 行,WILL 5 行等。“PRIOR ID”子句有助于处理每个原始行的多行。
with hist_employee(id, employee, start_yr, end_yr) as (
select 1, 'JOHN', 2013, 2014 from dual union all
select 2, 'WILL', 2012, 2016 from dual union all
select 3, 'MARK', 2012, 2012 from dual
)
select employee, start_yr, end_yr, (start_yr + (level-1)) as YR
from hist_employee
connect by level <= end_yr-start_yr+1
and prior id = id
and prior sys_guid() is not null
order by id;
EMPLOYEE START_YR END_YR YR
-------- ---------- ---------- ----------
JOHN 2013 2014 2013
JOHN 2013 2014 2014
WILL 2012 2016 2012
WILL 2012 2016 2013
WILL 2012 2016 2014
WILL 2012 2016 2015
WILL 2012 2016 2016
MARK 2012 2012 2012
8 rows selected.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.