开发者

Using the model clause to expand dates

I have several different types of data involving date range that I want to merge together, but at the same time broken down by day. So a 3 day piece of data would result in three rows:

start    primary_key
start+1  primary_key
start+2  primary_key

I've been playing around using the model clause of the select 开发者_如何学Gostatement in 10g and was looking for the best way to achieve this. Currently I'm joining a range of dates that covers the full range of possible dates (select min(start date), max(end date)). I'd prefer to be selecting the data and adding in more rows to transform it to a per day dataset.

edit:

I've managed to come up with (now includes sample data):

    SELECT * FROM (
        SELECT 123 req_code, 
               345 req_par_code, 
               TO_DATE('01-03-2010', 'dd-mm-yyyy') req_start_date, 
               TO_DATE('05-03-2010', 'dd-mm-yyyy') req_end_date
        FROM dual
)

    MODEL 
        PARTITION BY (req_code)
        DIMENSION BY (0 d)
        MEASURES     (SYSDATE dt, req_par_code, req_start_date, req_end_date)
        RULES ITERATE(365) UNTIL (dt[iteration_number] >= TRUNC(req_end_date[0])) (
            dt[iteration_number] = NVL(dt[iteration_number-1] + 1, TRUNC(req_start_date[0])),

            --Copy data across
            req_par_code[ iteration_number ] = req_par_code[0],
            req_start_date[ iteration_number ] = req_start_date[0],
            req_end_date[ iteration_number ] = req_end_date[0]
        )
    ORDER BY dt, req_code;


you can use the MODEL clause to generate rows, here's a small example:

SQL> SELECT * FROM t_data;

        PK START_DATE  END_DATE
---------- ----------- -----------
         1 20/01/2010  20/01/2010
         2 21/01/2010  23/01/2010
         3 24/01/2010  27/01/2010

SQL> SELECT pk, start_date, end_date FROM t_data
  2  MODEL
  3     PARTITION BY (pk)
  4     DIMENSION BY (0 AS i)
  5     MEASURES(start_date, end_date)
  6     RULES
  7     (  start_date[FOR i
  8                   FROM 1 TO end_date[0]-start_date[0]
  9                   INCREMENT 1] = start_date[0] + cv(i),
 10        end_date[ANY] = start_date[CV()] + 1
 11     )
 12  ORDER BY 1,2;

        PK START_DATE  END_DATE
---------- ----------- -----------
         1 20/01/2010  21/01/2010
         2 21/01/2010  22/01/2010
         2 22/01/2010  23/01/2010
         2 23/01/2010  24/01/2010
         3 24/01/2010  25/01/2010
         3 25/01/2010  26/01/2010
         3 26/01/2010  27/01/2010
         3 27/01/2010  28/01/2010


SELECT  TO_DATE('01.01.2009', 'dd.mm.yyyy') + level - 1
FROM    dual
CONNECT BY
        TO_DATE('01.01.2009', 'dd.mm.yyyy') + level <= TRUNC(SYSDATE, 'DDD') + 1

will give you the list of all dates from Jan 1st, 2009 till today.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜