以下是我要做的事情:我有一些数据代表了学生应该通过给定基准(在这种情况下,6月15日)达到的目标。我正在查看一个事务表并运行一些汇总查询,这些查询试图找出在给定时间点有多少学生“在轨道上”,使用“填补数据空白”和“填补空白”中描述的技术库存表'用于计算运行/累计总数并加密数据。 http://download.oracle.com/docs/cd/B28359_01/server.111/b28313/analysis.htm#i1014934
为了表达学生在表格中每一行的“目标进展”,我试图逐步计算到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并希望在数据库中执行,如果可能的话。
谢谢!
答案 0 :(得分:1)
这很大程度上取决于你对一周的定义。 IW
和IYYY
格式使用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;
答案 1 :(得分: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')
或
TO_DATE( '2011-43', 'YYYY-IW')
取决于您是否使用ISO周数。见http://www.techonthenet.com/oracle/functions/to_date.php。
我更喜欢周日午夜识别一周的方式;它非常直观(“2011年11月13日开始的一周”),并以直截了当的方式处理年终翻转。