列出Oracle中两个日期之间的所有日期

时间:2015-07-26 23:00:19

标签: oracle postgresql

我正在将postgres应用转换为Oracle应用。

我遇到了这个问题:

WITH cost AS (SELECT 
    well_schedules.id,
    generate_series(well_schedules.start_date::timestamp, well_schedules.end_date, '1 Day') AS "Date",
    (well_schedules.drilling_engineering_estimate * well_schedules.well_estimated_working_interest)/((well_schedules.end_date - well_schedules.start_date) + 1) AS "Cost Per Day"
FROM 
    well_schedules
    )

SELECT date_trunc('quarter', "Date"), COUNT("Cost Per Day"), id
FROM  cost
GROUP BY  id, date_trunc('quarter', "Date")
ORDER BY  date_trunc('quarter', "Date")

我正在努力的部分是generate_series行。

该行需要start_dateend_date,并列出这两个日期之间的所有日期。我们需要这些信息来编制每天/每周/每月/每季度/每年的报告(或者至少我们假设我们需要这些信息)。

我们的数据如下:

well_schedules

| id | start_date   | end_date     | cost |
| 1  | '2015-01-01' | '2015-03-20' | 100  |

我们假设cost_per_day在所有日期都相同,因此我们要生成一份报告,让我们查看cost_per_daycost_per_weekcost_per_monthcost_per_yearcost_per_quartercost_per_week/month/quarter/year的计算方法是,按星期/月/季度/年对天数进行分组,并将相关的cost_per_days

相加

2 个答案:

答案 0 :(得分:0)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE well_schedules ( id, start_date, end_date, cost ) AS
SELECT 1 , DATE '2015-01-01', DATE '2015-01-20', 100 FROM DUAL;

查询1

SELECT ID,
       COLUMN_VALUE AS Day,
       COST / ( end_date - start_date + 1 ) AS Cost_per_day
FROM   well_schedules,
       TABLE (
         CAST(
           MULTISET(
             SELECT start_date + LEVEL - 1
             FROM   DUAL
             CONNECT BY start_date + LEVEL - 1 <= end_date
           )
           AS SYS.ODCIDATELIST
         )
       )

<强> Results

| ID |                       DAY | COST_PER_DAY |
|----|---------------------------|--------------|
|  1 | January, 01 2015 00:00:00 |            5 |
|  1 | January, 02 2015 00:00:00 |            5 |
|  1 | January, 03 2015 00:00:00 |            5 |
|  1 | January, 04 2015 00:00:00 |            5 |
|  1 | January, 05 2015 00:00:00 |            5 |
|  1 | January, 06 2015 00:00:00 |            5 |
|  1 | January, 07 2015 00:00:00 |            5 |
|  1 | January, 08 2015 00:00:00 |            5 |
|  1 | January, 09 2015 00:00:00 |            5 |
|  1 | January, 10 2015 00:00:00 |            5 |
|  1 | January, 11 2015 00:00:00 |            5 |
|  1 | January, 12 2015 00:00:00 |            5 |
|  1 | January, 13 2015 00:00:00 |            5 |
|  1 | January, 14 2015 00:00:00 |            5 |
|  1 | January, 15 2015 00:00:00 |            5 |
|  1 | January, 16 2015 00:00:00 |            5 |
|  1 | January, 17 2015 00:00:00 |            5 |
|  1 | January, 18 2015 00:00:00 |            5 |
|  1 | January, 19 2015 00:00:00 |            5 |
|  1 | January, 20 2015 00:00:00 |            5 |

答案 1 :(得分:0)

我会建议下面的代码考虑两个日期的当月的第一天和最后一天:

示例:

Date Initial: 01/10/2014  
Date Final: 12/21/2018  

代码将返回:

01/01/2014  
02/01/2014  
03/01/2014  
04/01/2014  
...  
12/28/2018  
12/29/2018  
12/30/2018  
12/31/2018  

守则:

SELECT
     CAL.DT AS "Date"

    ,TO_NUMBER(TO_CHAR(CAL.DT,'DD')) AS "Day"

    ,TO_NUMBER(TO_CHAR(CAL.DT,'MM')) AS "Month"

    ,TO_NUMBER(TO_CHAR(CAL.DT,'YY')) AS "YearYY"

    ,TO_NUMBER(TO_CHAR(CAL.DT,'YYYY')) AS "YearYYYY"

    ,TO_CHAR(CAL.DT,'day') AS "Description_Day"

    ,TO_CHAR(CAL.DT,'dy') AS "Description_Day_Abrev"

    ,TO_CHAR(CAL.DT,'Month') AS "Description_Month"

    ,TO_CHAR(CAL.DT,'Mon') AS "Description_Month_Abrev"

    ,TO_CHAR(CAL.DT,'dd month yyyy') AS "Date_Text"

FROM (
    SELECT
        (
            TO_DATE(SEQ.MM || SEQ.YYYY, 'MM/YYYY')-1
        ) + SEQ.NUM AS "DT"
    FROM
    (
        SELECT RESULT NUM, 
        TO_CHAR(( -- Minimum Date
            TO_DATE('01/01/2014', 'DD/MM/YYYY')
            ) , 'MM') AS "MM",
        TO_CHAR(( -- Minimum Date
            TO_DATE('01/01/2014', 'DD/MM/YYYY')
            ) , 'YYYY') AS "YYYY"
        FROM
        (
            SELECT ROWNUM RESULT FROM DUAL CONNECT BY LEVEL <= (
                (
                -- Maximum Date 
                LAST_DAY(TO_DATE('31/12/2018', 'DD/MM/YYYY')) -- Always Last Day
                -
                -- Maximum Date
                TRUNC(TO_DATE('01/01/2014', 'DD/MM/YYYY')) -- Always First Day of Month
                ) + 1 -- Because the First Day (RESULT) don't begin at zero
            )
        ) -- How many sequences (RESULT) to generate
    ) SEQ
) CAL
    ;