在此question中,我能够在
中插入日期|----------|----------|
| DT | FLAG |
|----------|----------|
| 2015-MAY | E |
| 2015-JUN | H |
| 2015-OCT | E |
| 2016-FEB | E |
|----------|----------|
获取(使用FLAG
V
|----------|----------|
| DT | FLAG |
|----------|----------|
| 2015-MAY | E |
| 2015-JUN | H |
| 2015-JUL | V |
| 2015-AUG | V |
| 2015-SEP | V |
| 2015-OCT | E |
| 2015-NOV | V |
| 2015-DEC | V |
| 2016-JAN | V |
| 2016-FEB | E |
|----------|----------|
使用以下代码:
CREATE OR REPLACE PROCEDURE FILL_DATE_GAP AS
BEGIN
INSERT INTO DUMMY_DATES
SELECT to_date(add_months(date '2015-01-01', level - 1), 'yyyy-mm-dd') mth,
'V'
FROM DUAL
connect by level <= 14
MINUS
SELECT DT,
FLAG
FROM DUMMY_DATES;
END FILL_DATE_GAP;
我想对下表做同样的事情:
|----------|----------|----------|
| EID | DT | FLAG |
|----------|----------|----------|
| 123 | 2015-MAY | E |
| 123 | 2015-JUN | H |
| 123 | 2015-OCT | E |
| 123 | 2016-FEB | E |
|----------|----------|----------|
获得:
|----------|----------|----------|
| EID | DT | FLAG |
|----------|----------|----------|
| 123 | 2015-MAY | E |
| 123 | 2015-JUN | H |
| 123 | 2015-JUL | V |
| 123 | 2015-AUG | V |
| 123 | 2015-SEP | V |
| 123 | 2015-OCT | E |
| 123 | 2015-NOV | V |
| 123 | 2015-DEC | V |
| 123 | 2016-JAN | V |
| 123 | 2016-FEB | E |
|----------|----------|----------|
问题 有人能告诉我怎么做(复制EID)吗?
答案 0 :(得分:0)
您在这里寻找的是执行一些数据密集化,填补数据空白。
从稀疏填充表开始,使用分区外连接到密集维表,您可以实现目标:
With Date_Dim(dt) as (
select date '2015-05-01'
+ numtoyminterval(level-1,'month')
from dual
connect by level <= 14
)
select t1.eid
, dd.dt
, nvl(t1.flag, 'V') flag
from Date_Dim dd
left join YourData t1 partition by (t1.EID)
on t1.dt = dd.dt;
在上面的代码中,我将Date_Dim公用表表达式(CTE)定义为密集日期维度,并将其外部连接到YourData,通过EID列对连接进行分区。仅此一项将确保对于每个eid值,Date_Dim表中的每个DT值至少会有一行。最后一点是确保您的标志列返回&#39; V&#39;而不是NULL,只需在查询投影中使用NVL函数处理。
这里有SQL Fiddle显示它的实际效果,以及上述查询在该小提琴中生成的输出:
<强> Results 强>:
| EID | DT | FLAG |
|-----|----------------------|------|
| 123 | 2015-05-01T00:00:00Z | E |
| 123 | 2015-06-01T00:00:00Z | H |
| 123 | 2015-07-01T00:00:00Z | V |
| 123 | 2015-08-01T00:00:00Z | V |
| 123 | 2015-09-01T00:00:00Z | V |
| 123 | 2015-10-01T00:00:00Z | E |
| 123 | 2015-11-01T00:00:00Z | V |
| 123 | 2015-12-01T00:00:00Z | V |
| 123 | 2016-01-01T00:00:00Z | V |
| 123 | 2016-02-01T00:00:00Z | E |
| 123 | 2016-03-01T00:00:00Z | V |
| 123 | 2016-04-01T00:00:00Z | V |
| 123 | 2016-05-01T00:00:00Z | V |
| 123 | 2016-06-01T00:00:00Z | V |
如果您想要一个适合插入缺少的EID / Date列的源表的查询,可以在WHERE子句中添加t1.flag为null。
<强>替代地强>
如果您希望查询更像原始版本,则可以使用交叉产品生成所有行并减去原始数据:
With Date_Dim(dt) as (
select date '2015-05-01'
+ numtoyminterval(level-1,'month')
from dual
connect by level <= 14
)
select t1.eid, dd.dt, 'V'
from Date_Dim dd
cross join YourData t1
minus
select eid, dt, 'V' from YourData
答案 1 :(得分:0)
如果有兴趣,请按照以下方式开展工作:
FOR employee_rec IN c_employee
LOOP
INSERT INTO XE_GRID_OUTPUT
SELECT i_employerId,
employee_rec.EMPLOYEEID,
to_date(add_months(date '2014-01-01', level - 1), 'YYYY-MM-DD') mth,
'V'
FROM DUAL
CONNECT BY LEVEL <= 14
MINUS
SELECT EMPLOYERID, EMPLOYEEID, DECLARATIONPERIOD, FLAG
FROM XE_GRID_OUTPUT
WHERE EMPLOYEEID=employee_rec.EMPLOYEEID;
END LOOP;
光标选择给定的employeeId的EMPLOYEEID。