How to iterate over a date range in PL/SQL

前端 未结 7 1919
梦毁少年i
梦毁少年i 2020-12-29 12:56

I need to write a report that generates summary totals against a table with date ranges for each record.

table data:
option   start_date   end_date
opt1              


        
7条回答
  •  半阙折子戏
    2020-12-29 13:23

    This type of query is best handled if you have a second "utility" table, which you can use for just about any query where you need to convert ranges into specific buckets. The utility table is nothing more than a list of numbers:

    CREATE TABLE Iterator (Counter NUMBER);
    
    COUNTER
    -------
          0
          1
          2
          3 
    ...
        100 (or however many rows you want to include)
    

    IF we assume that you want to display 30 days, e.g.

    SELECT   TO_DATE('6/1/2009', 'MM/DD/YYYY') + i.counter thedate
           , i.My_option
           , count(y.My_option)
        FROM ( SELECT DISTINCT
                      i2.Counter
                    , y.My_option
                 FROM iterator i2
                    , YourTable y
                WHERE i2.Counter < 5
             ) i
               LEFT OUTER JOIN yourtable y 
                               ON  TO_DATE('6/1/2009', 'MM/DD/YYYY') + i.counter 
                                   >= y.start_date
                               AND TO_DATE('6/1/2009', 'MM/DD/YYYY') + i.counter 
                                   <  y.end_date
                               AND y.My_option = i.My_option
    GROUP BY TO_DATE('6/1/2009', 'MM/DD/YYYY') + i.counter
           , i.My_option
    ORDER BY 1
           , 2;
    

    The idea is that you create a Cartesian product between your iterator table and your table with the range, then filter out all the cases where your range conditions aren't met. You can use this in many places, and is one of the best examples why it is better to model your data with ranges as opposed to discrete intervals - because you can always convert easily to discrete intervals using this technique.

    edit: I really shouldn't use BETWEEN for date range queries - I changed it to >= <

提交回复
热议问题