自2000年以来的天数,周数,月数,年数,季度

时间:2013-02-01 16:29:47

标签: sql datetime oracle11g

我需要使用以下内容填充Oracle 11g数据库中的日历表: CALENDAR_DATE, WEEK_NUMBER, week_year, day_since_2000, week_since_2000, month_since_2000, quarter_since_2000, WEEK_OF_MONTH

自2000年以来,该表已经填充了数据我现在需要将其填充到1994年,其中包含Since_2000列的负数。我想我已经有了一切,但自2000年以来的一周和2000年以来的一个季度。

EDIT1:刚刚注意到自2000年以来的200周和一个月我的一周仍然搞砸了。使用下面提到的答案后,自2000年以来的季度看起来很好我正在使用最新版本更新查询。

EDIT2:由于缺少trunc()而无法正常工作。它的工作正常。最新查询已更新。

这就是我用来做的事情:

/* Formatted on 2/1/2013 11:54:27 AM (QP5 v5.227.12220.39724) */
CREATE OR REPLACE PROCEDURE populate_d_calendar (start_date     IN DATE,
                         end_date       IN DATE)
AS
BEGIN
   INSERT INTO d_calendar (calendar_date,
               week_number,
               week_year,
               day_since_2000,
               week_since_2000,
               month_since_2000,
               quarter_since_2000,
               week_of_month)
      SELECT dt,                                                        --Date
         TO_CHAR (dt,
              'ww'),                                --Week in the year
         TO_CHAR (dt,
              'yyyy'),                                          --Year
         TO_CHAR (dt - end_date),                         --Day Since 2000
         TRUNC (TO_CHAR (dt - end_date) / 7),            --Week Since 2000
         TRUNC (MONTHS_BETWEEN (dt,
                    end_date)),             --Month Since 2000
         CASE
        WHEN TO_CHAR (dt,
                  'MMDD') >= '0101'
         AND TO_CHAR (dt,
                  'MMDD') < '0401'
        THEN
             0
           +   4
             * TRUNC (  MONTHS_BETWEEN (TO_DATE (   '0101'
                             || TO_CHAR (dt,
                                     'yyyy'),
                             'mmddyyyy'),
                        TO_DATE ('01Jun2000'))
                  / 12)                                       --q1
        WHEN TO_CHAR (dt,
                  'MMDD') >= '0401'
         AND TO_CHAR (dt,
                  'MMDD') < '0701'
        THEN
             1
           +   4
             * TRUNC (  MONTHS_BETWEEN (TO_DATE (   '0101'
                             || TO_CHAR (dt,
                                     'yyyy'),
                             'mmddyyyy'),
                        TO_DATE ('01Jun2000'))
                  / 12)                                       --q2
        WHEN TO_CHAR (dt,
                  'MMDD') >= '0701'
         AND TO_CHAR (dt,
                  'MMDD') < '1001'
        THEN
             2
           +   4
             * TRUNC (  MONTHS_BETWEEN (TO_DATE (   '0101'
                             || TO_CHAR (dt,
                                     'yyyy'),
                             'mmddyyyy'),
                        TO_DATE ('01Jun2000'))
                  / 12)                                       --q3
        WHEN TO_CHAR (dt,
                  'MMDD') >= '1001'
         AND TO_CHAR (dt,
                  'MMDD') <= '1231'
        THEN
             3
           +   4
             * TRUNC (  MONTHS_BETWEEN (TO_DATE (   '0101'
                             || TO_CHAR (dt,
                                     'yyyy'),
                             'mmddyyyy'),
                        TO_DATE ('01Jun2000'))
                  / 12)                                       --q4
         END
        quarters_since_2000,                      --Quarter Since 2000
         TO_CHAR (dt,
              'w')                                 --Week of the month
    FROM (SELECT start_date + LEVEL - 1 dt
        FROM DUAL
          CONNECT BY LEVEL <= end_date - start_date + 1);
END;
/

3 个答案:

答案 0 :(得分:1)

我认为你可能会像其他人一样经历一个浮动点,所以也许:

TO_CHAR (dt - end_date)/7 week_since_2000

(MONTHS_BETWEEN (dt,
            end_date)/3) quarter_since_2000

答案 1 :(得分:1)

,您可以按照以下方法之一进行操作:

http://searchoracle.techtarget.com/answer/Calculating-weeks-between-two-dates

因为它取决于哪些规则对您更有用

宿舍,请使用:

case 
         WHEN TO_CHAR (dt,'MMDD') >= '0101' and TO_CHAR (dt,'MMDD') < '0401' then  0 + 4 * trunc(months_between( to_date('0101' || to_char(dt,'yyyy'),'mmddyyyy'),to_date('01Jun2000' )) /12)   --q1
         WHEN TO_CHAR (dt,'MMDD') >= '0401' and TO_CHAR (dt,'MMDD') < '0701' then  1 + 4 * trunc(months_between( to_date('0101' || to_char(dt,'yyyy'),'mmddyyyy'),to_date('01Jun2000' )) /12)  --q2
         WHEN TO_CHAR (dt,'MMDD') >= '0701' and TO_CHAR (dt,'MMDD') < '1001' then  2 + 4 * trunc(months_between( to_date('0101' || to_char(dt,'yyyy'),'mmddyyyy'),to_date('01Jun2000' )) /12)  --q3
         WHEN TO_CHAR (dt,'MMDD') >= '1001' and TO_CHAR (dt,'MMDD') <= '1231' then 3 + 4 * trunc(months_between( to_date('0101' || to_char(dt,'yyyy'),'mmddyyyy'),to_date('01Jun2000' )) /12)   --q4
         end         quarters_since_2000,  

答案 2 :(得分:1)

这是从2013年1月1日至今的我的日历表版本。我不知道你怎么需要插入月,季,日等数量...你需要显示每年或一次之间的总月数?您可以自己添加这些计算或在帖子中添加所需的输出以使其清晰。请参阅下面的addl查询/评论:

-- Days,weeks, quarters from 1/1/2013 --
SELECT start_date                               -- 1/1/2013 --
    , TRUNC(start_date, 'iw')                  wk_starts  
    , TRUNC(start_date, 'iw') + 7 - 1/86400    wk_ends
    , TO_NUMBER (TO_CHAR (start_date, 'IW'))   ISO_wk#  
    , TO_NUMBER (TO_CHAR (start_date, 'Q'))    Quarters  
 FROM
  (
   SELECT TRUNC(SYSDATE, 'Y')-1 + LEVEL AS start_date  
     FROM dual
   CONNECT BY LEVEL <= 
  (  -- replace this part to go back to 1994 - see below --
  SELECT TRUNC(ADD_MONTHS (SYSDATE, 12), 'Y')-TRUNC(SYSDATE, 'Y') "Num of Days in 2013"   
    FROM dual
  )
)
/

START_DATE  WK_STARTS   WK_ENDS                 ISO_WK#     QUARTERS
---------------------------------------------------------------------
1/1/2013    12/31/2012  1/6/2013 11:59:59 PM    1           1
1/2/2013    12/31/2012  1/6/2013 11:59:59 PM    1           1
......
2/19/2013   2/18/2013   2/24/2013 11:59:59 PM   8           1
2/20/2013   2/18/2013   2/24/2013 11:59:59 PM   8           1
......
3/10/2013   3/4/2013    3/10/2013 11:59:59 PM   10          1
3/11/2013   3/11/2013   3/17/2013 11:59:59 PM   11          1
.......

-- 6971 days from 1/1/1994 till today - 2/1/2013 --
SELECT TRUNC(SYSDATE) - TRUNC(ADD_MONTHS (SYSDATE, -12*19), 'Y') "Num of Days from 1994"
  FROM dual
/

-- 4780 days from 1/1/2000 till today - 2/1/2013 --
SELECT TRUNC(SYSDATE) - TRUNC(ADD_MONTHS (SYSDATE, -12*13), 'Y') "Num of Days from 2000"
  FROM dual
/

-- 156 Months between from 2000 toll today --
SELECT MONTHS_BETWEEN(TRUNC(SYSDATE), TRUNC(ADD_MONTHS (SYSDATE, -12*13))) mo_btw_2000_till_today 
  FROM dual
/

-- Number of weeks btw. 2 dates -- 
SELECT to_char(sysdate, 'WW') - to_char(sysdate-30, 'WW') number_of_weeks FROM dual
/

这可能不是您想要的...为了帮助您,我需要查看查询的实际预期输出。只是想帮忙......