Вычисление оставшегося времени для данного ориентира (в неделях) в Oracle - PullRequest
1 голос
/ 15 ноября 2011

Вот что я собираюсь сделать: у меня есть некоторые данные, которые представляют цель, которую студенты должны достичь с помощью данного теста (в данном случае, 15 июня).Я просматриваю транзакционную таблицу и запускаю несколько сводных запросов, которые пытаются выяснить, сколько учеников было «на пути» в данный момент времени, используя методы, описанные в «Заполнение пробелов в данных» и «Заполнение пробелов вТаблица инвентаризации »для расчета текущих / накопленных итогов и уплотнения данных.http://download.oracle.com/docs/cd/B28359_01/server.111/b28313/analysis.htm#i1014934

Чтобы выразить «прогресс ученика в достижении цели» в каждой строке таблицы, я пытаюсь частично определить, сколько времени осталось до 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

(15 июня - 24-я неделя 2012 года).Есть ли более элегантный хотя бы немного верный способ сделать это?Каждый раз, когда я пытаюсь выполнить вычисления с использованием функций даты, я получаю недопустимое число, или литерал не соответствует ошибкам строки формата.

Казалось, что кто-то достиг чего-то, в некоторой степени связанного с тем, что я пытался сделать здесь: https://forums.oracle.com/forums/thread.jspa?threadID=633028 но я не уверен, что перестроение этой даты с использованием IYYY и IW приведет меня туда, куда я хочуgo.

Используя Oracle 11gR2 Express и хотите сделать это в базе данных, если это вообще возможно.

Спасибо!

Ответы [ 2 ]

1 голос
/ 16 ноября 2011

Это будет во многом зависеть от вашего определения недели. Форматы IW и IYYY используют стандарт ISO, согласно которому неделя всегда начинается в понедельник и длится 7 дней. Это означает, что по стандарту 01.01.2011 была частью 52-й недели 2010 года. Если это не сработает для вас, вам нужно начать с точного определения того, что вы подразумеваете под неделей.

Поскольку стандарт 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 голосов
/ 15 ноября 2011
trunc (to_date('15-jun-2012') - sysdate)

даст вам количество календарных дней с настоящего момента до 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.

Я предпочитаю способ определения недели в воскресенье-полночь; он довольно интуитивно понятен («Неделя начинается с 13 ноября 2011 года») и обрабатывает переходы на конец года простым способом.

...