What does the to_char function do? - oracle

Here's the complete code:
SELECT last_name, hire_name, To_char(hired_date, 'DAY') "Day"
from employees
order by to_char(hire_date -1,'d')
I want to understand this part of the code.
to_char (hire_date -1, 'd')
Can someone explain me how does the to_char function work?

this is oracle.
What happens ( as far as i get it) is that it takes the day of a date minus one day. Hope this helps you understand it.
So,
TO_Char(hired_date -1, day)
T0_Char = method name
hired_date = orginional date
-1 = orignional date minus 1 day
day = return the the day ( Sunday , Monday wensday)

TO_CHAR is just a converter for the type coming out of the select query, chances are that the data can't be interrogated properly without conversion, the -1 bit (if that's also confusing you) is going to give you the day before the hire date.

Related

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.

Query sysdate against field in SQL Developer

SELECT LAST_MAINTAIN, PLANE_ID
FROM PLANE
WHERE MONTHS BETWEEN(
(TO_DATE('sysdate', 'MM/DD/YYYY'),
TO_DATE('LAST_MAINTAIN', 'MM/DD/YYYY')))
>24;
I am trying to select Last_Maintain, a date field, from the Plane table and return results that have 2 years between today's date and the last maintenance. Does anyone know what is wrong? I have a feeling I am using months between incorrectly but I'm not sure. Thanks
Edit: Adjusted location of sysdate and Last_Maintain, still erroring out saying I'm missing a parentheses (right), even though I went through all my parentheses without seeing one missing.
Edit2: Tried out
SELECT *
FROM plane
WHERE MONTHS BETWEEN (sysdate, last_maintain ) > 24;
Still telling me I need more parentheses.
Edit3: Problem is resolved, here is the final code that worked:
SELECT *
FROM plane
WHERE MONTHS_BETWEEN (sysdate, last_maintain) > 24;
Don't call to_date on a date. to_date converts a string to a date. It would only make sense to pass a string to to_date.
sysdate is a function that returns a date. That is very, very different from a literal string sysdate
You probably want
SELECT *
FROM plane
WHERE months_between( sysdate, last_maintain ) > 24
MONTHS_BETWEEN returns the result as first - second, so in your case, all values are < 0. Put sysdate first.
From Oracle doc:
"If date1 is earlier than date2, then the result is negative"

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

Oracle - Another way for month query?

first... sorry for my english.
I have a query like this:
Select *
From tableA
Where (
TO_NUMBER(TO_CHAR(dateA(+),'SYYYY')) = 2013
AND TO_NUMBER(TO_CHAR(dateA(+),'MM')) = 02
AND to_number(to_char(dateA(+),'dd')) <= 25
)
and retrieve me the data from each date until last number that I give as parameter, in this case the day 25. This working but delay very much because the form of "Where" statement... anybody know another way that retrieve the data so fast and with the same functionality?
It sounds like you want
SELECT *
FROM tableA
WHERE dateA BETWEEN trunc( date '2013-02-26', 'MM' ) AND date '2013-02-26'
This will return all the rows where dateA is between the first of the month and the specified date. If there is an index on dateA, Oracle would be able to use it for this sort of query (though whether it actually would is a separate issue).

Adding one month to saved date(oracle)

I have a table A which contains a Date type attribute. I want to write a query to select the date in another table B with value one month after the value in A.Any one know how to do it in oracle?
uhm... This was the first hit on google:
http://psoug.org/reference/date_func.html
It seems you're looking for the "add_months" function.
You need to use the ADD_MONTHS function in Oracle.
http://www.techonthenet.com/oracle/functions/add_months.php
Additional info: If you want to use this function with today's date you can use ADD_MONTHS(SYSDATE, 1) to get one month from now.
The question is to select a date_field from table b where date_field of table b is one month ahead of a date_field in table a.
An additional requirement must be taken into consideration which is currently unspecified in the question. Are we interested in whole months (days of month not taken into consideration) or do we want to include the days which might disqualify dates that are one month ahead but only by a couple of days (example: a=2011-04-30 and b=2011-05-01, b is 1 month ahead but only by 1 day).
In the first case, we must truncate both dates to their year and month values:
SELECT TRUNC( TO_DATE('2011-04-22','yyyy-mm-dd'), 'mm') as trunc_date
FROM dual;
gives:
trunc_date
----------
2011-04-01
In the second case we don't have to modify the dates.
At least two approaches can be used to solve the initial problem:
First one revolves around adding one month to the date_field in table a and finding a row in table b with a matching date.
SELECT b.date_field
FROM tab_a as a
,tab_b as b
WHERE ADD_MONTHS( TRUNC( a.date_field, 'mm' ), 1) = TRUNC( b.date_field, 'mm' )
;
Note the truncated dates. Leaving this out will require a perfect day to day match between dates.
The second approaches is based on calculating the difference in months between two dates and picking a calculation that gives a 1 month difference.
SELECT b.date_field
FROM tab_a as a
,tab_b as b
WHERE months_between( TRUNC( b.date_field, 'mm') , TRUNC(a.date_field, 'mm') ) = 1
The order of the fields in months_between is important here. In the provided example:
for b.date_field one month ahead of a.date_field the value is 1
for b.date_field one month before a.date_field the value is -1 (negative one)
Reversing the order will also reverse the results.
Hope this answers your question.

Resources