2016-02-12 1 views
1

У меня есть диапазон дат кристалла, который используется для временного листа. (То, что я унаследовал) Я ищу помощь в том, как изменить это в часть моего SQL запроса из Oracle для отчета SSRSПреобразование хрустального кода отчета в Oracle SQL-запрос для диапазона дат

Today - Round((((Today - Date (1998,11,23))/14) - Truncate((Today - Date (1998,11,23))/14)) * 14,0) 

Спасибо заранее Стивен (который до сих пор очень новый SQL и SSRS отчетов)

+0

Используйте 'sysdate()' для 'Today',' to_date (1998-11-23, 'yyyy-mm-dd') 'for' Date (1998,11,23) '. – Spidey

+0

@nimesh Нужно будет поместить тики вокруг ''1998-11-23'' – xQbert

+0

@xQbert Вправо, пропустил это. – Spidey

ответ

0

прямой перевод того, что у вас есть, кажется:

trunc(sysdate) - round((((trunc(sysdate) - date '1998-11-23')/14) - trunc((trunc(sysdate) - date '1998-11-23')/14)) * 14,0) 

Но вы можете упростить, что:

trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14) 

Два звонка trunc(sysdate) дают текущую дату со временем, усеченным до полуночи, поэтому в настоящее время 2016-02-12. Если вычесть фиксированную дату начала (? Предположительно самый первый период в вашей системе), вы получите номер, from how Oracle does datetime arithmetic:

select trunc(sysdate) - date '1998-11-23' from dual; 

     TRUNC(SYSDATE)-DATE'1998-11-23' 
--------------------------------------- 
            6290 

Поскольку оба дат были в полночи, что это целое число - целое число дней между сегодня и фиксированную дату. Если вы разделите это на 14, вы получите 449.285, что составляет 449 целых двухнедельных периодов и 0,285 текущего. Исходный расчет принимает это и удаляет усеченную версию 449, чтобы просто уйти с .285, а затем умножить на 14, чтобы вернуть эту оставшуюся часть в виде целого числа, которое равно 4.

Но это именно то, что дает the mod() function - остаток n2 делится на n1 ". Другими словами, mod(6290, 14) - это остаток от 6290, деленный на 14, что также равно 4. Он получает тот же результат от одного выражения вместо двух.

Итак, вы просто вычтите рассчитанное значение 4 с текущего дня, которое сегодня скажет вам об этом до 2016-02-08.


Видя, как это меняет для выбора сгенерированных дат:

with t (dt) as (
    select trunc(sysdate) - level from dual connect by level < 21 
) 
select dt, 
    dt - round((((dt - date '1998-11-23')/14) - trunc((dt - date '1998-11-23')/14)) * 14) long_version, 
    dt - mod(dt - date '1998-11-23', 14) period_start, 
    dt - mod(dt - date '1998-11-23', 14) + 14 period_end 
from t 
order by dt; 

DT   LONG_VERSION PERIOD_START PERIOD_END 
---------- ------------ ------------ ---------- 
2016-01-23 2016-01-11 2016-01-11 2016-01-25 
2016-01-24 2016-01-11 2016-01-11 2016-01-25 
2016-01-25 2016-01-25 2016-01-25 2016-02-08 
2016-01-26 2016-01-25 2016-01-25 2016-02-08 
... 
2016-02-06 2016-01-25 2016-01-25 2016-02-08 
2016-02-07 2016-01-25 2016-01-25 2016-02-08 
2016-02-08 2016-02-08 2016-02-08 2016-02-22 
2016-02-09 2016-02-08 2016-02-08 2016-02-22 
2016-02-10 2016-02-08 2016-02-08 2016-02-22 
2016-02-11 2016-02-08 2016-02-08 2016-02-22 

Вы можете получить в конце периода путем добавления дней к результату, или вычислить его отдельно, используя дату начала 14 дней , Если вы ищете для записей в диапазоне вы могли бы сделать:

where some_date >= trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14) 
and some_date < trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14) + 14 

Если ни одна из дат, когда нет времени после полуночи (который может быть случаем для расписания) можно использовать between и сделать конец периода 13 дней спустя, как вы предложили вы сейчас делаете в комментарии:

where some_date between trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14) 
and trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14) + 13 

Я предпочитаю> = и < подход, хотя, как это не будет вам подножку, когда вы делаете что-то на данных, где раз действительно важно.

+0

Alex Я не буду притворяться, что полностью понимаю, что вы написали, но я буду переваривать его и понять, прежде чем использовать его. Спасибо – aquariumjunky

+0

@aquariumjunky - Я добавил некоторое объяснение того, что делает короткая версия расчета; надеюсь, это поможет. –

Смежные вопросы