SQL按日期复制行直到今天

时间:2014-10-31 09:44:46

标签: sql excel oracle date plsql

仅供参考日期格式:YYYY.MM.DD我希望每行增加1个月

我在excel中有以下示例表:

id   date    price
1  2013.01.01 20
2  2014.03.01 30
3  2014.04.01 30
4  2010.01.01 10

我需要插入到数据库中以复制所有行,直到今天:

id    date   price
1  2013.01.01 20
1  2013.02.01 20
1  2013.03.01 20
1  2013.04.01 20
....
1  2014.10.01 20
2  2014.03.01 30
...
2  2014.10.01 30
...
4  2010.01.01 10
...
4  2010.10.01 10

你能给我一些建议吗,我的第一个想法是生成日期的JAVA代码,但java数据函数不是我最好的。而且我想用SQL或PL / SQL 或者excel来解决它。

2 个答案:

答案 0 :(得分:3)

假设您的数据确实存在于表中,如果您有数字列表,则可以解决此问题。这是一个解决方案:

with m as (
      select trunc(sysdate) - min(date) + 1 as numdays
      from tablename t
     ),
     n as (
      select level - 1 as n
      from m
      connect by level <= m.numdays + 1
     )
select id, date + n.n as date, price
from tablename t join
     n
     on date + n.n <= sysdate;

编辑:

要按月执行此操作,我认为以下情况应该有效:

with m as (
      select months_between(trunc(sysdate), min(date)) + 1 as nummonths
      from tablename t
     ),
     n as (
      select level - 1 as n
      from m
      connect by level <= m.nummonths + 1
     )
select id, add_months(date, n.n) as date, price
from tablename t join
     n
     on add_months(date, n.n) <= sysdate;

答案 1 :(得分:1)

我假设id是数据集中的唯一键。您可以将此数据传输到Oracle表,然后编写函数来为您完成剩下的工作。

    SQL> 
SQL> CREATE TABLE test_table(
  2  ID NUMBER,
  3  DATE1 DATE,
  4  price number);
Table created

SQL> 
SQL> INSERT INTO test_table VALUES(1,to_date('2014.10.25','yyyy.mm.dd'),20);
1 row inserted
SQL> INSERT INTO test_table VALUES(2,to_date('2014.10.27','yyyy.mm.dd'),30);
1 row inserted
SQL> INSERT INTO test_table VALUES(3,to_date('2014.10.28','yyyy.mm.dd'),30);
1 row inserted
SQL> INSERT INTO test_table VALUES(4,to_date('2014.10.31','yyyy.mm.dd'),10);
1 row inserted

SQL> commit;
Commit complete

SQL> SELECT * FROM test_table ORDER BY ID,date1;
        ID DATE1            PRICE
---------- ----------- ----------
         1 10/25/2014          20
         2 10/27/2014          30
         3 10/28/2014          30
         4 10/31/2014          10

SQL> 
SQL> CREATE OR REPLACE PROCEDURE p_test_fill_dup IS
  2  CURSOR c_data IS SELECT ID,date1,price FROM test_table;
  3  BEGIN
  4  
  5  FOR r_data IN c_data LOOP
  6    IF TRUNC(SYSDATE) = trunc(r_data.date1) THEN CONTINUE; END IF;
  7    FOR i IN 1..(TRUNC(SYSDATE) - r_data.date1) LOOP
  8      INSERT INTO test_table VALUES(r_data.id,r_data.date1+i,r_data.price);
  9      END LOOP;
 10      END LOOP;
 11      COMMIT;
 12  END     p_test_fill_dup;
 13  /
Procedure created

SQL> 
SQL> begin
  2    -- Call the procedure
  3    p_test_fill_dup;
  4  end;
  5  /
PL/SQL procedure successfully completed

SQL> SELECT * FROM test_table ORDER BY ID,date1;
        ID DATE1            PRICE
---------- ----------- ----------
         1 10/25/2014          20
         1 10/26/2014          20
         1 10/27/2014          20
         1 10/28/2014          20
         1 10/29/2014          20
         1 10/30/2014          20
         1 10/31/2014          20
         2 10/27/2014          30
         2 10/28/2014          30
         2 10/29/2014          30
         2 10/30/2014          30
         2 10/31/2014          30
         3 10/28/2014          30
         3 10/29/2014          30
         3 10/30/2014          30
         3 10/31/2014          30
         4 10/31/2014          10
17 rows selected

如果您想使用以下步骤添加月份直到当月:

CREATE OR REPLACE PROCEDURE p_test_fill_dup IS
    CURSOR c_data IS SELECT ID,date1,price FROM test_table;
    BEGIN

    FOR r_data IN c_data LOOP
      IF TRUNC(months_between(SYSDATE,r_data.date1))=0 THEN CONTINUE; END IF;

      FOR i IN 1..TRUNC(months_between(SYSDATE,r_data.date1)) LOOP
        INSERT INTO test_table VALUES(r_data.id,add_months(r_data.date1,i),r_data.price);
        END LOOP;
       END LOOP;
       COMMIT;
   END     p_test_fill_dup;
相关问题