Oracle BI: Select all records from last week - oracle

I need to get all records with a date between Sunday and Saturday last week, inclusive, for whatever date the query is run. For today, April 19th 2011, that would be from April 10th to April 16th.
When I entered the dates manually and converted the filter to SQL, I got the following syntax:
RESOLVED_DATE BETWEEN timestamp '2011-04-10 00:00:00' AND timestamp '2011-04-16 00:00:00'
I'm not even sure this is correct, because it seems to exclude dates on the 16th itself (shouldn't the time be 23:59:59?)

It is possible to determine the dates you want using combinations of next_day and regular date arithmetic. Below code should be pretty close, but it's untested and probably fails on some corner case, but at least you get the general idea :)
where resolved_date >= next_day( trunc(sysdate) - interval '14' day, 'SUN')
and resolved_date < next_day( trunc(sysdate) - interval '7' day, 'SUN')
trunc(sysdate) truncate the date to day; 2011-04-19 23:32:34 becomes 2011-04-19 00:00:00, i.e. removing the time component.
next_day(sysdate, 'SUN') returns the next sunday. If sysdate happens to be a sunday, the next sunday is returned.
Important: The day names have to be in the same language as your session.
The interval thing is just a standard way of adding/subtracting different units of time from a date.
Putting it all together, the logic for the 19th of April 2011 would be:
Truncate sysdate => 2011-04-19 00:00:00
subtract 14 days => 2011-04-05 00:00:00
Find the next sunday => 2011-04-10 00:00:00
...and
Truncate sysdate => 2011-04-19 00:00:00
subtract 7 days => 2011-04-12 00:00:00
Find the next sunday => 2011-04-17 00:00:00
..resulting in the following query:
where resolved_date >= timestamp '2011-04-10 00:00:00'
and resolved_date < timestamp '2011-04-17 00:00:00'
All resolved_dates that happened on or after the first second of the 10:th but before the first second of the 17:th would be included. Note that >= and < isn't equivalent to between.
A note on performance: I would make sure that Oracle correctly estimates the date range to be 7 days, and that the correct join order/method is used. If you expect the query to run for a while, you can afford to calculate the dates in the application and supply them as date litterals instead of computing them on the fly like I did above.

take a look at the to_date function: http://psoug.org/reference/builtin_functions.html

Related

Oracle sql how to get the date of a week

I have the following query that gets the week of a date:
SELECT pdm.serie, rta.matricula_ant, TO_CHAR (fecha, 'ww') semana,
SUM (rta.kms_acumulados) kms,
COUNT
(DISTINCT (CASE
WHEN v.secuencia BETWEEN rta.sec_origen AND rta.sec_destino
THEN v.cod_inc
ELSE '0'
END
)
)
- 1 numincidencias
FROM (SELECT ms.tren, ms.fecha_origen_tren, ms.secuencia, ri.cod_inc
FROM r_incidencias ri, mer_sitra ms
WHERE ri.cod_serv = ms.tren
AND ri.fecha_origen_tren = ms.fecha_origen_tren
AND ri.cod_tipoin IN (SELECT cod_tipo_iincidencia
FROM v_tipos_incidencias
WHERE grupo = '45')
AND ri.punto_desde = ms.cod_estacion) v,
r_trenes_asignar rta,
r_maquinas rm,
planificador.pl_dh_material pdm
WHERE rta.fecha BETWEEN TO_DATE ('21/09/2018', 'dd/mm/yyyy') AND TO_DATE ('21/09/2018',
'dd/mm/yyyy'
)
AND rta.serie >= 4000
AND rta.matricula_ant IS NOT NULL
AND rm.matricula_maq = rta.matricula_ant
AND rm.cod_serie = pdm.id_material
AND rta.grafico BETWEEN pdm.desde AND pdm.hasta
AND v.tren(+) = rta.tren
AND v.fecha_origen_tren(+) = rta.fecha
GROUP BY pdm.serie, rta.matricula_ant, TO_CHAR (fecha, 'ww')
ORDER BY pdm.serie, rta.matricula_ant, TO_CHAR (fecha, 'ww')
For example week 1
I want to display
week 1 : 1 january - 7 january
How can I get this?
Oracle offers the TRUNC(datestamp, format) function to manipulate dates this way. You may use a variety of format strings to get the first day of a quarter, year, or even the top of the hour.
Given a particular datestamp value, Oracle returns midnight on the first day of the present week with this expression:
TRUNC(datestamp,'DY')
You can add days to a datestamp. Therefore this expression gives you midnight on the last day of the week
TRUNC(datestamp,'DY') + 6
A WHERE-clause selector for all rows in the present week might be this.
WHERE datestamp >= TRUNC(SYSDATE,'DY')
AND datestamp < TRUNC(SYSDATE,'DY') + 7
Notice that the end of the range is just before (<) midnight on the first day of the next week. You need that because you may have datestamps after midnight on the last day of the week. (Beware using BETWEEN for datestamp ranges.)
And,
SELECT TO_CHAR(TRUNC(SYSDATE,'DY'),'YYYY-MM-DD'),
TO_CHAR(TRUNC(SYSDATE,'DY')+6,'YYYY-MM-DD')
FROM DUAL;
displays the first and last dates of the present week in ISO-like format.
Date arithmetic is cool. It's worth your trouble to study the date-arithmetic functions in your DBMS at least once a year.

How can I use an expression in my where clause to return a dynamic date range for my query

I am working in BIDS 2008r2 on a SSRS report that pulls data from an Oracle database.
I have a where clause that uses a hard date range, I want to change it to an expression that will dynamically change as time progresses.
This is the where clause that currently works to return the 1st day of the previous month to the last day of the previous month. ie I am looking for all data from the previous month
WHERE CHRGDTTM BETWEEN {ts '2015-12-01 00:00:00'} AND {ts '2015-12-31 23:59:00'}
I have written an expression that returns the beginning of last month:
DateAdd(DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))
and one that returns the end of last month:
DateAdd(DateInterval.Minute, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))
How do I get those into my where clause?
Thank you.
If you want to do this entirely within the Oracle where clause you can do:
WHERE CHRGDTTM >= ADD_MONTHS(TRUNC(sysdate, 'MM'), -1)
AND CHRGDTTM < TRUNC(sysdate, 'MM')
The TRUNC(date) function truncates the supplied date - the system date in this case; by default it removes the time part so gives you midnight this morning, but this modified that behaviour with the MM format model, and gives you midnight on the first of the current month. So today TRUNC(SYSDATE, 'MM') gives you 2016-01-26 00:00:00. You can use that as it is for the upper end of your date range.
The ADD_MONTHS() function, well, adds a number of months, -1 here to give you 2015-12-01 00:00:00 instead. Put together that gives you everything from 2015-12-01 00:00:00 up to, but no including, 2016-01-01 00:00:00, which is equivalent to your BETWEEN range.
You could also use an interval calculation to get the start of the previous month:
WHERE CHRGDTTM >= TRUNC(sysdate, 'MM') - INTERVAL '1' MONTH
AND CHRGDTTM < TRUNC(sysdate, 'MM')
which has the same effect, and is safe as you're always going to end up with a valid date from the calculation; dates at the ends of months can be more problematic.
You can read more about datetime/interval arithmetic in the documentation.
As an alternative, you can create two parameters of type Date/Time and set the Default Values for the parameters with the expressions you've developed. Then in the query it just becomes WHERE CHRGDTTM BETWEEN :StartDate AND :EndDate. If the user needn't worry about this, set the visibility to Hidden for both.

extract week number from date postgres

I would like to extract the week number as:
2015-52
from a date formatted as:
2015-12-27
How can I perform this in postgres?
my weeks are calculated from monday to sunday.
To get the year and the week in a single character value, use to_char()
select to_char(current_date, 'IYYY-IW');
IW returns the year and the week number as defined in the ISO standard and IYYY returns the corresponding year (which might be the previous year).
If you need the year and the week number as numbers, use extract
select extract('isoyear' from current_date) as year,
extract('week' from current_date) as week;
I have done like this
extract(week from cast(current_date as date))
extract(year from cast(current_date as date))
As same with #a_horse_with_no_name, but be careful there is a little difference between extract('isoyear' from current_date) and extract('year' from current_date) if current_date is within week0 in new year(the last week(53) of last year), especially when you extract week as well.
For example:
The follow output is 2020 not 2021
select EXTRACT('isoyear' from to_timestamp('2021-01-02 17:37:27', 'YYYY-MM-DD hh24:mn:ss')) as year
The follow output is 2021
select EXTRACT('year' from to_timestamp('2021-01-02 17:37:27', 'YYYY-MM-DD hh24:mn:ss')) as year

Calculate the week ending date in oracle using Saturday as the week end date

Given a field in Oracle that contains dates, how would you calculate what the week ending date is using Sun thru Sat as your week. For example, if the date is 1/26/2015 (which is a Monday), the query should return 1/31/2015 (which is a Saturday. If the date is 1/31/2015, then the query should return 1/31/2015.
Given any particular date / time value, this expression will return midnight of the preceding Sunday.
TRUNC(whatever_time,'DAY')
So, you can do stuff like this:
SELECT TRUNC(whatever_time,'DAY') week_starting,
TRUNC(whatever_time,'DAY') + 6 week_ending,
SUM(sales)
FROM table
GROUP BY TRUNC(whatever_time,'DAY')
and you'll get what you need.
Notice that TRUNC(whatever_time,'DAY') honors the Oracle session initialization parameter called “NLS_TERRITORY”. For example, in Europe Monday is considered the first business day of the week. Try this.
ALTER SESSION SET NLS_TERRITORY=GERMANY;
SELECT TRUNC( DATE '2013-12-31', 'DAY'),
TRUNC( DATE '2014-01-03', 'DAY')
FROM DUAL;
A complete writeup of this is here: http://www.plumislandmedia.net/sql-time-processing/using-sql-report-time-intervals-oracle/

Oracle ORA-01839: date not valid for month specified Leap Year

Oracle 11g
here is a quick one hopefully.
Below is part of a script that gets date only from from the next month
first day of next month to last day. But today 29th feb it thrown an error of
ORA-01839: date not valid for month specified
M.MS_DATE between trunc(sysdate + interval '1' month,'MM') and last_day(sysdate + interval '1' month)
Is there a way round this. Many thanks
I have seen this as well and I consider this a bug in Oracle.
The workaround is to use add_months() instead :
between trunc(add_months(sysdate,1),'MM') and last_day(add_months(sysdate,1));
I would probably use add_months() as a_horse_with_no_name suggests, but just as an alternative if you want to use intervals, you can move the point you do the truncation in the first expression, and include the same truncation in the second expression:
select trunc(sysdate, 'MM') + interval '1' month as first_day,
last_day(trunc(sysdate, 'MM') + interval '1' month) as last_day
from dual;
FIRST_DAY LAST_DAY
---------- ----------
2015-02-01 2015-02-28
This works because all months have a first day, so you don't trip over the documented caveat.
When interval calculations return a datetime value, the result must be an actual datetime value or the database returns an error

Resources