2011-11-15 31 views
1

以下是我所要做的:我有一些数据代表学生应该达到给定基准的目标(在本例中为6月15日) 。我正在查看一个交易表并运行一些汇总查询,这些查询试图找出在给定时间点有多少学生“正在跟踪”,使用“填充数据中的差距”和“填充间隙”中描述的技术库存表“来计算运行/累计总数并且使数据致密化。 http://download.oracle.com/docs/cd/B28359_01/server.111/b28313/analysis.htm#i1014934在Oracle中计算给定基准(以星期为单位)的剩余时间

为了表达学生进步的目标“在表中的每一行,我想分数找出多少当年被留下,直到6月15日,让我运行总比作按比例分级的目标版本。

我的数据是这样的:

Measure Goal  Year Week Date (YYYY-WW) 
106141  400000 2011 42  2011-42 
128886  400000 2011 43  2011-43 
145449  400000 2011 44  2011-44 
156921  400000 2011 45  2011-45 

我有一种变通方法,但它确实哈克和可怕。

,case 
    when year = 2012 then 24 - week 
    when year = 2011 then (52 - week) + 24 
    else null 
end as weeks_to_june_15 

(6月15日是2012年的第24周)。有没有更优雅的甚至可以稍微正确地做到这一点?每次我使用日期函数尝试计算时,都会收到非法数字或文字与格式字符串错误不匹配的情况。

这似乎是一个人完成一定的相关性是什么,我想在这里做一些事情:https://forums.oracle.com/forums/thread.jspa?threadID=633028 ,但我不知道,如果使用IYYY重建该日期和IW会得到我在哪里,我想去的地方。

使用Oracle 11gR2 Express并想要这样做数据库中,如果可能的话。

谢谢!

回答

1

这将取决于您对一周的定义。 IWIYYY格式使用ISO标准,表明一周总是在星期一开始并持续7天。这意味着,按照标准,2011年1月1日是2010年第52周的一部分。如果这不适用于您,那么您需要先准确定义一周内的含义。

由于ISO标准是明确定义的,因此您可以将一周的第一天视为等同于本周,这将允许您准确使用日期数学。下面是一个可以做到这一点的功能。你也可以在SQL中完成所有工作,但是PL/SQL使得这种事情变得简单易懂。

CREATE OR REPLACE FUNCTION week_diff(p_year NUMBER, 
            p_week NUMBER, 
            p_end_date DATE) 
    RETURN NUMBER AS 
    v_end_date DATE; 
    v_start_date DATE; 
    v_weeks  NUMBER; 
    v_last_week DATE; 
BEGIN 
    v_end_date  := TRUNC(TO_DATE(p_end_date, 'mm/dd/yyyy'), 'IW'); 
    v_start_date := TRUNC(TO_DATE('2/1/' || p_year, 'mm/dd/yyyy'), 'IYYY') 
        + (p_week * 7); 

    IF TRUNC(v_end_date, 'IYYY') = TRUNC(v_start_date, 'IYYY') THEN 
     v_weeks := (v_end_date - v_start_date)/7; 
    ELSE 
     v_last_week := TRUNC(TO_DATE('12/31/' || TO_CHAR(v_start_date, 'yyyy'), 
            'mm/dd/yyyy'), 'IW'); 
     v_weeks  := (v_last_week - v_start_date)/7 
         + TO_NUMBER(TO_DATE(v_end_date, 'IW')); 
    END IF; 

    RETURN v_weeks; 
END week_diff; 
0
trunc (to_date('15-jun-2012') - sysdate) 

会给你从现在到6月15日之间的日历天数。

这应该让你开始。

如果你有一个存储日期/时间数据项,这样表达:

trunc (stored,'DAY') 

产生前面的周日(见http://www.techonthenet.com/oracle/functions/trunc_date.php)午夜,因此,例如,

select count(*) events_per_week, 
     trunc(event_time,'DAY') week_starting 
    from event 
group by trunc(event_time,'DAY') 

会告诉你每周你在事件表中有多少事件。这是逐周总结数据的一种有价值的方式,因为它适用于短期和多年的时间段。

如果您的业务规则要求您的星期一从星期一开始,请改为执行此操作。

1+trunc(stored-1,'DAY') 

如果你想从像 '2011-43' 日期/时间数据项,然后做

TO_DATE( '2011-43', 'YYYY-WW')

取决于您是否使用ISO星期编号。

to_date('2011-43','YYYY-IW')

http://www.techonthenet.com/oracle/functions/to_date.php

我更喜欢星期日至午夜的方式来确定一个星期;阅读起来非常直观(“2011年11月13日开始的一周”),并以直接的方式处理年终翻车事件。

+0

当你有日子的时候,我和你在日历算术上 - 但是当你有汇总的数据(每周一个值)时会有些不同。如果数据的格式为2011-43(YYYY-WW),你将如何进行计算? – Andrew

+0

在我的回答中看到进一步的讨论。 –