1

这就是我要做的事情:我有一些数据代表学生应该通过给定基准(在本例中为 6 月 15 日)达到的目标。我正在查看一个事务表并运行一些汇总查询,试图找出在给定时间点有多少学生“在轨道上”,使用“填补数据空白”和“填补空白Inventory Table' 用于计算运行/累积总数并加密数据。 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 并希望数据库中执行此操作。

谢谢!

4

2 回答 2

1

这在很大程度上取决于您对一周的定义。IW和格式使用 ISO 标准,该IYYY标准规定一周总是从星期一开始,持续 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;
于 2011-11-15T23:21:11.033 回答
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 日开始的一周”)并以直接的方式处理年终展期。

于 2011-11-15T00:49:47.800 回答