2016-02-12 2 views
1

J'ai une plage de dates de rapport de cristal utilisée pour une feuille de temps. (Quelque chose que je hérité) Je suis à la recherche de l'aide sur la façon de changer cela en partie de ma requête SQL sur Oracle pour un rapport de SSRSConversion d'un code de rapport de cristal en requête SQL Oracle pour la plage de dates

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

Merci à l'avance Steven (qui est encore très nouveau pour sql et SSRS rapports)

+0

Utilisez 'sysdate()' pour 'Today',' to_date (1998-11-23, 'aaaa-mm-jj') 'pour' Date (1998,11,23) '. – Spidey

+0

@nimesh Devra mettre des tics autour de '' 1998-11-23'' – xQbert

+0

@xQbert Droit, raté ça. – Spidey

Répondre

0

La traduction directe de ce que vous avez semble être:

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

Mais vous pouvez simplifier cela à:

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

Les deux appels trunc(sysdate) donnent la date actuelle avec le temps tronqué à minuit, donc actuellement 2016-02-12. Si vous soustrayez votre date de départ fixe (? Sans doute la première période de votre système), vous obtenez un numéro, from how Oracle does datetime arithmetic:

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

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

Parce que les deux dates étaient à minuit qui est un nombre entier - le nombre total de jours entre aujourd'hui et la date fixe. Si vous divisez cela par 14, vous obtenez 449,285, soit 449 périodes entières de deux semaines, et .285 de la période actuelle. Votre calcul original prend cela et supprime la version tronquée 449 pour laisser juste .285, puis multiples que par 14 pour obtenir cette partie restante en tant que nombre entier, qui est 4.

Mais c'est exactement ce que the mod() function vous donne - " le reste de n2 divisé par n1 ". En d'autres termes, mod(6290, 14) est le reste de 6290 divisé par 14, qui est également 4. Il obtient le même résultat d'une expression au lieu de deux. Alors, il vous suffit de soustraire cette valeur calculée de 4 du jour actuel, ce qui vous rappelle aujourd'hui 2016-02-08.


En voyant comment cela change pour une sélection de dates générées:

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 

Vous pouvez obtenir la fin de la période en ajoutant jours au résultat, ou calculer séparément à l'aide d'une date de début 14 jours plus tard . Si vous êtes à la recherche d'enregistrements dans une plage que vous pouvez alors faire:

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 

Si aucune des dates ont jamais après minuit (ce qui peut être le cas pour une feuille de temps), vous pouvez utiliser between et faire la période de fin 13 jours plus tard, comme vous le suggérez que vous faites actuellement dans un commentaire:

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 

Je préfère> = et < approche bien, car il vous ne se déclenche pas lorsque vous faites quelque chose sur les données où le les temps comptent aussi.

+0

Alex Je ne vais pas prétendre comprendre entièrement ce que vous avez écrit mais je vais le digérer et le comprendre avant de l'utiliser. Merci – aquariumjunky

+0

@aquariumjunky - J'ai ajouté quelques explications sur ce que fait la version courte du calcul; J'espère que cela pourra aider. –