Using current system month inside date functions - oracle

I am trying to write a query in Noetix that is pulling data from Oracle EBS. The query will have a column that checks to see if the date range of a field value of each record is within the current month then, if so, return another value. For example, the field value might be "23 JUN 2022", and I want to check to see if this date is within the "current" month.
So that I don't have to manually edit the report every time a month turns, I want the function to be 'rolling' where it checks the system time for the current month instead of me hard coding it in. I have the following expression, which works, but is static:
case
when
"TABLE1"."Scheduled_Date" >= TO_DATE('01 Jun 2022','DD Mon YYYY') AND
"TABLE1"."Scheduled_Date" < TO_DATE('01 Jul 2022','DD Mon YYYY') THEN
"TABLE1"."Selling_Price"
ELSE
TO_NUMBER('0')
END
How do I replace "Jun" and "Jul" in the expression above with a SYSDATE function that returns the current system month (for Jun), and the current system month +1 (for Jul)? I am experienced at MS Access SQL, but Oracle SQL is new to me. I can't figure out the proper syntax.

for the 1st day of the actual month you can use
add_months(last_day(trunc(sysdate))+1, -1)
for the 1st day of the next month you can use
last_day(trunc(sysdate))+1

There are various options you might choose; here's one of them (I'm setting date format so that you'd recognize values being returned; you don't have to do that):
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select trunc(sysdate, 'mm') first_of_this_month,
2 add_months(trunc(sysdate, 'mm'), 1) first_of_next_nonth
3 from dual;
FIRST_OF_THIS_MONTH FIRST_OF_NEXT_NONTH
------------------- -------------------
01.06.2022 00:00:00 01.07.2022 00:00:00
SQL>
Applied to your code:
case when "TABLE1"."Scheduled_Date" >= trunc(sysdate, 'mm')
AND "TABLE1"."Scheduled_Date" < add_months(trunc(sysdate, 'mm'), 1)
THEN
"TABLE1"."Selling_Price"
ELSE
TO_NUMBER('0')
END

Related

How do I separate the time and date in SQL navigator?

I am trying to separate the time and date in one column to be independent off each other. I am new at writing scripts
this is my query:
select
*
from
[tablename]
where
to_date([column_name]) in ( '15-Jun-2021', '16-Jun-2021' )
and
to_char([column_name],'dd-Mon-yyyy HH:MM:ss') < '15-Jun-2021 19:54:30'
The way you put it, it would be
select *
from your_table
where date_column >= date '2021-06-15'
and date_column < to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss')
because
date_column should be of date datatype. If it isn't, you'll have problems of many kinds in the future. Therefore,
don't to_date it, it is already a date
don't to_char it either, because you'd be comparing strings and get unexpected result. Use that function when you want to nicely display the result
the second condition you wrote makes the first one questionable. If date_column is less than value you wrote, then you can omit date '2021-06-16' from the first condition because you won't get any rows for that date anyway
date literal (date '2021-06-15') sets time to midnight, so condition I wrote should return rows you want
SQL> select date '2021-06-15' first,
2 to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss') second
3 from dual;
FIRST SECOND
------------------- -------------------
15.06.2021 00:00:00 15.06.2021 19:54:30
SQL>

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.

Oracle DB to_date with year - to_date(2017,'YYYY') unexpected return

While writing few queries I needed to return only those rows that have date column set in this year (2017) , that's not my problem I know how to write this query in couple of diffrent ways, but I came across something strange and unexpected for me. Can anyone explain why Oracle db 11.2 is behaving this way?
select sysdate from dual
returns:
2017/12/05 09:22:27
select to_date(2017,'YYYY'),trunc(sysdate,'YYYY') from dual
returns :
2017/12/01 00:00:00 2017/01/01 00:00:00
select to_date(2017,'YYYY'),trunc(sysdate,'YYYY') from dual
where trunc(sysdate,'YYYY') = to_date(2017,'YYYY')
no rows returned
Why does to_date(2017,'YYYY') returns 2017/12/01, will it return 2017/01/01 next month? Why does it work that way? I would expect it to always return 2017/01/01 no matter the current month (if month part is indeed changing depending on sysdate).
In Oracle, TO_DATE will assume that:
If you do not specify the year then it is the current year;
If you do not specify the month then it is the current month;
If you do not specify the day then it is the first day of the month;
If you do not specify the hours then it is the midnight hour (0);
If you do not specify the minutes then it is 0 minutes past the hour; and
If you do not specify the seconds then it is 0 seconds into the minute.
You are specifying only the year (2017) so it will be:
Zero minutes and seconds past midnight of the first day of the current month of the year you specify (2017).
If you want the first day of the year then specify the month (and preferably the rest of the date):
select to_date( '201701','YYYYMM'),
trunc(sysdate,'YYYY')
from dual
where trunc(sysdate,'YYYY') = to_date( '201701','YYYYMM' )
Or use a date literal:
select DATE '2017-01-01',
trunc(sysdate,'YYYY')
from dual
where trunc(sysdate,'YYYY') = DATE '2017-01-01'

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.

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/

Resources