проблемы с разделением дат по сезонам года в SQL - PullRequest
0 голосов
/ 22 июня 2011

У меня есть измерение TIME в моем DW, и я хочу добавить лагерь, чтобы заполнить его временем года. Я хочу сделать что-то вроде этого:

create or replace
PROCEDURE "PROC_UPDATE_SEASON" 

IS 
CURSOR curs IS   
SELECT * FROM indw.time FOR UPDATE;  
 cur_d NUMBER;   
 cur_m NUMBER;   
 start_d NUMBER;   
 start_m NUMBER;   
 end_d NUMBER;   
 end_m NUMBER;
 cur_Date DATE;     

 BEGIN 
 FOR cs IN curs 
 LOOP 
     cur_d := to_number(to_char(cs.time_DAY,'dd')); 
     cur_m := to_number(to_char(cs.time_DAY,'mm')); 
     cur_date:= cs.time_DAY; -- this is my date dd-mm-yyyy or dd/mm/yyyy


     if ((cur_date in format dd/mm is >= 21/12 and <=31/12) OR cur_date>=01/01 and <=20/03) 
     UPDATE time t set t.time_SEASON = 'Winter' WHERE CURRENT OF curs; 
     else if cur_date_in format dd/mm is between a date and another then it's Spring)
       -- and so on ... 
     END LOOP; 
 END;

Есть ли способ добиться этого, используя to_char и to_date? Я пытаюсь, но всегда получаю ошибки :( и сравнение месяца и дня по отдельности было бы огромной и, IMO, глупой работой.

Не могли бы вы дать мне несколько советов?

Я на самом деле просто использую что-то вроде дд / мм <= another_date_with_only_day_and_month </p>

Ответы [ 3 ]

5 голосов
/ 22 июня 2011

Нет необходимости в курсоре и цикле:

update indw.time
set t.time_SEASON = case
                      when to_char(time_DAY,'MMDD') between '1221' and '1231' 
                        or to_char(time_DAY,'MMDD') between '0101' and '0320' 
                         then 'Winter'
                      when ...
                    end 

Более того, в Oracle 11G вы можете добавить виртуальный столбец в таблицу на основе этого выражения CASE, чтобы каждая строка автоматически имела правильный временной_сезон без необходимости обновления.

0 голосов
/ 28 июня 2018

Я бы сделал так, чтобы получить сезон от даты:

CASE
    WHEN EXTRACT(MONTH FROM time_DAY) IN (12,1,2) THEN 'winter'
    WHEN EXTRACT(MONTH FROM time_DAY) IN (3,4,5) THEN 'spring'
    WHEN EXTRACT(MONTH FROM time_DAY) IN (6,7,8) THEN 'summer'
    WHEN EXTRACT(MONTH FROM time_DAY) IN (9,10,11) THEN 'fall'
END season
0 голосов
/ 22 июня 2011

У меня нет доступа к Oracle, чтобы играть с опциями для вас.Но у меня есть один совет:
- Если этот код выполняется часто, будьте осторожны с использованием преобразования строк и сравнения строк, они обычно ужасно медленны по сравнению с числовой обработкой
- Но, если это только изредкаиспользовать, идти с тем, что проще всего, и винт производительности :)

Имея это в виду, я бы использовал EXTRACT ... (Обратите внимание, как я уже сказал, я не могу это проверить)

UPDATE indw.time
SET    t.time_SEASON = CASE
                         WHEN EXTRACT(MONTH, time_DAY) < 3 THEN 'Winter'
                         WHEN EXTRACT(MONTH, time_DAY) = 3 THEN
                           CASE WHEN EXTRACT(DAY, time_DAY) <= 20 THEN 'Winter' ELSE 'Spring' END
                         WHEN EXTRACT(MONTH, time_DAY) < 6 THEN 'Spring'
                         WHEN EXTRACT(MONTH, time_DAY) = 6 THEN
                           CASE WHEN EXTRACT(DAY, time_DAY) <= 20 THEN 'Spring' ELSE 'Summer' END
                         WHEN EXTRACT(MONTH, time_DAY) < 9 THEN 'Summer'
                         WHEN EXTRACT(MONTH, time_DAY) = 9 THEN
                           CASE WHEN EXTRACT(DAY, time_DAY) <= 20 THEN 'Summer' ELSE 'Autumn' END
                         WHEN EXTRACT(MONTH, time_DAY) < 12 THEN 'Autumn'
                         WHEN EXTRACT(MONTH, time_DAY) = 12 THEN
                           CASE WHEN EXTRACT(DAY, time_DAY) <= 20 THEN 'Autumn' ELSE 'Winter' END
                       END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...