Add days Oracle SQL - sql

SELECT ORDER_NUM, CUSTOMER_NUM, CUSTOMER_NAME, ADD_DAYS (ORDER_DATE, 20)
FROM CUSTOMER, ORDERS;
Oracle Express says ADD_DAYS invalid? Any ideas what Am I doing wrong?

If you want to add N days to your days. You can use the plus operator as follows -
SELECT ( SYSDATE + N ) FROM DUAL;

You can use the plus operator to add days to a date.
order_date + 20

In a more general way you can use "INTERVAL". Here some examples:
1) add a day
select sysdate + INTERVAL '1' DAY from dual;
2) add 20 days
select sysdate + INTERVAL '20' DAY from dual;
2) add some minutes
select sysdate + INTERVAL '15' MINUTE from dual;

Some disadvantage of "INTERVAL '1' DAY" is that bind variables cannot be used for the number of days added. Instead, numtodsinterval can be used, like in this small example:
select trunc(sysdate) + numtodsinterval(:x, 'day') tag
from dual
See also: NUMTODSINTERVAL in Oracle Database Online Documentation

It's Simple.You can use
select (sysdate+2) as new_date from dual;
This will add two days from current date.

One thing about
select (sysdate+3) from dual
is that the sysdate is interpreted as date.
But if you want to use a custom date, not local, you need to make sure it is interpreted as date, not string. Like so (adding 3 days):
select (to_date('01/01/2020')+3) from dual

Related

How to extract No. of Days between 2 dates in oracle sql?

I want No. of days between these 2 dates using Oracle SQL
Dates:
BETWEEN "1/1/2018" AND "6/11/2018"
How to write SQL Query?
between date '2018-01-01' and date '2018-11-06'
where DATE literal looks exactly like that: DATE 'YYYY-MM-DD'
In your example:
double quote's can't be used
even if you used single quotes, that would be a string, not DATE so you'd depend on whether Oracle is capable of converting it (implicitly) to date or not
therefore, always use dates, not strings
[EDIT]
This is how you select the whole calendar between those two dates:
select date '2018-01-01' + level - 1
from dual
connect by level <= date '2018-11-06' - date '2018-01-01' + 1;
As other answers have pointed out you can simply divide two dates, but there is also no need for any additional arithmetic.
The code:
select to_date('6/11/2018', 'DD/MM/YYYY') - to_date('1/1/2018', 'DD/MM/YYYY')
from dual;
The result: 309
you can simple do:
select date1-date2 form dual;
or
select (sysdate-to_date('01-jan-2018'))-(sysdate-to_date('10-jan-2018'))from dual;
Just use
select date'2018-11-06' - date'2018-01-01' + 1 as days_difference
from dual;
DAYS_DIFFERENCE
---------------
310
or
with t( myDate ) as
(
select date'2018-11-06' from dual union all
select date'2018-01-01' from dual
)
select max(myDate) - min(myDate) + 1 as days_difference
from t;
DAYS_DIFFERENCE
---------------
310

Query to produce data only within the asked hour range

Oracle SQL:
I been trying to get this some snippet of query working. When you run it, it prompts you for an hour, and displays no records. I don’t want the query to have a static hour as it will need to be run 4 times a day.
So from the ‘&date’ input, I want it to show data for the past 24 hours. Is that possible?
dt_time = timestamp(6) field
select distinct to_char(dt_ time,'dd/mm/yyyy hh24'), fault_description
from order
where to_char(dt_time,'hh24') <= '&date' -24
order by to_char(dt_ time,'dd/mm/yyyy hh24');
Example, if you enter 10 (when query executed) it will show the data from 10(:00) through to 10(:00)next day
[Hope there is enough info for someone to answer, please]
Use a combination of between and interval:
where dt_time between
to_date(&date, 'ddmmyyyy hh24') and
to_date(&date, 'ddmmyyyy hh24') + interval '24' hour
You'll need to pass/parse the input date as a full date and not only the hour part, in order to prevent unexpected results.
You can use NUMTODSINTERVAL in a CTE to get the hour as user input.
WITH t_hour( h ) AS
( SELECT NUMTODSINTERVAL(&d,'HOUR' ) h FROM DUAL
)
SELECT DISTINCT TO_CHAR(dt_time,'dd/mm/yyyy hh24'),
fault_description
FROM ORDER
CROSS JOIN t_hour
WHERE dt_time BETWEEN TRUNC(SYSDATE) + h AND TRUNC(SYSDATE) + 1 + h
ORDER BY 1;
You need to make use of SYSDATE as you are fetching last one day data.
Also if you add or subtract number with a date column the offset will be number of days, not number of hours. So you need to use &date/24
Try this:
select distinct to_char(dt_time,'dd/mm/yyyy hh24'), fault_description
from order
where dt_time - &date / 24 between TRUNC(sysdate-1) and TRUNC(sysdate)
order by to_char(dt_ time,'dd/mm/yyyy hh24');
Please comment.
WHERE DATEDIFF(SYSDATE,DT_TIME) * 24 < &DATE AND DT_TIME < SYSDATE

SQL Oracle How to convert String Week into date

I have dates stored like String in database.
The format is 'yyyy-ww' (example: '2015-43').
I need to get the first day of the week.
I tried to convert this string into date but there is no 'ww' option for the function "to_date".
Do you have an idea to perform this convertion?
EDIT
Test results based on the answers -
Thanks for your anwsers, but I have many problems to apply your solutions to my context:
select
TRUNC ( 2015 + ((43 - 1) * 7), 'IW' )
from dual
==> Error : ORA-01722: invalid number
select
TRUNC(to_date('2015','YYYY')+ to_number('01') *7, 'IW')
from dual
==> 2015-02-02 00:00:00
I waited for a date in january
select
trunc(to_date(regexp_substr('2015-01', '\d+',1,2), 'YYYY') + regexp_substr('2015-01', '\d+') * 7, 'IW') dt2
from dual
==> 0039-09-14 00:00:00
select
regexp_substr('2015-01', '\d+',1,2) as res1,
regexp_substr('2015-01', '\d+') * 7 as res2
from dual
==> res1 = 01
==> res2 = 14105
try to use by truncate
with t as (
select '16-2010' dt from dual
)
--
--
select dt,
trunc(to_date(regexp_substr(dt, '\d+',1,2), 'YYYY') + regexp_substr(dt, '\d+') * 7, 'IW') dt2
from t
I have dates stored like String in database.
You should never do that. It is a bad design. you should store date as DATE and not as a string. For all kinds of requirements for date manipulations Oracle provides the required DATE functions and format models. As and when needed, you could extract/display the way you want.
I need to get the first day of the week.
TRUNC (dt, 'IW') returns the Monday on or before the given date.
Anyway, in your case, you have the literal as YYYY-WW format. You could first extract the year and week number and combine them together to get the date using TRUNC.
TRUNC ( year + ((week_number - 1) * 7)
, 'IW
)
So, the above should give you the Monday of the week number passed for that year.
SQL> WITH DATA AS
2 ( SELECT '2015-43' str FROM dual
3 )
4 SELECT TRUNC(to_date(SUBSTR(str, 1, 4),'YYYY')+ to_number(SUBSTR(str, instr(str, '-',1)+1))*7, 'IW')
5 FROM DATA
6 /
TRUNC(TO_
---------
23-NOV-15
SQL>
Similar to Lalit's, however, I think I've corrected the math (his seemed to be off a bit when I tested .. )
with w_data as (
select sysdate + level +200 d from dual connect by level <= 10
),
w_weeks as (
select d, to_char(d,'yyyy-iw') c
from w_data
)
SELECT d, c, trunc(d,'iw'),
TRUNC(
to_date(SUBSTR(c, 1, 4)||'0101','yyyymmdd')-8+to_char(to_date(SUBSTR(c, 1, 4)||'0101','yyyymmdd'),'d')
+to_number(SUBSTR(c, instr(c, '-',1)+1)-1)*7 ,'IW')
FROM w_weeks;
The extra columns help show the dates before, and after.
I would do the following:
WITH d1 AS (
SELECT '2015-43' AS mydate FROM dual
)
SELECT TRUNC(TRUNC(TO_DATE(REGEXP_SUBSTR(mydate, '^\d{4}'), 'YYYY'), 'YEAR') + (COALESCE(TO_NUMBER(REGEXP_SUBSTR(mydate, '\d+$')), 0)-1) * 7, 'IW')
FROM d1
The first thing the above query does is get the first four digits of the string 2015-43 and truncates that to the closest year (if you convert convert 2015 using TO_DATE() it returns a date within the current month; that is SELECT TO_DATE('2015', 'YYYY') FROM dual returns 01-FEB-2015; we need to truncate this value to the YEAR in order to get 01-JAN-2015). I then add the number of weeks minus one times seven and truncate the whole thing by IW. This returns a date of 01-OCT-2015 (see SQL Fiddle here).
According ISO the 4th of January is always in week 1, so your query should look like
Select
TRUNC(TO_DATE(REGEXP_SUBSTR(your_column, '^\d{4}')||'-01-04', 'YYYY-MM-DD')
+ 7*(REGEXP_SUBSTR(your_column, '\d$')-1), 'IW')
from your_table;
However, there is a problem. ISO year used for Week number can be different than actual year. For example, 1st Jan 2008 was in ISO week number 53 of 2007.
I think a proper working solution you get only when you generate ISO weeks from date value.
WITH w AS
(SELECT TO_CHAR(DATE '2010-01-04' + LEVEL * INTERVAL '7' DAY, 'IYYY-IW') AS week_number,
TRUNC(DATE '2010-01-04' + LEVEL * INTERVAL '7' DAY, 'IW') AS first_day
FROM dual
CONNECT BY DATE '2010-01-04' + LEVEL * INTERVAL '7' DAY < SYSDATE)
SELECT your_Column, first_day
FROM w your_table
JOIN w ON week_number = your_Column;
Your date range must bigger than 2010-01-04 and not bigger than current day.
This is what I used:
select
to_date(substr('2017/01',1,4)||'/'||to_char(to_number(substr('2017/01',6,2)*7)-5),'yyyy/ddd') from dual;

Oracle SQl Dev, how to calc num of weekdays between 2 dates

Does anyone know how can I calculate the number of weekdays between two date fields? I'm using oracle sql developer. I need to find the average of weekdays between multiple start and end dates. So I need to get the count of days for each record so I can average them out. Is this something that can be done as one line in the SELECT part of my query?
This answer is similar to Nicholas's, which isn't a surprise because you need a subquery with a CONNECT BY to spin out a list of dates. The dates can then be counted while checking for the day of the week. The difference here is that it shows how to get the weekday count value on each line of the results:
SELECT
FromDate,
ThruDate,
(SELECT COUNT(*)
FROM DUAL
WHERE TO_CHAR(FromDate + LEVEL - 1, 'DY') NOT IN ('SAT', 'SUN')
CONNECT BY LEVEL <= ThruDate - FromDate + 1
) AS Weekday_Count
FROM myTable
The count is inclusive, meaning it includes FromDate and ThruDate. This query assumes that your dates don't have a time component; if they do you'll need to TRUNC the date columns in the subquery.
You could do it the following way :
Lets say we want to know how many weekdays between start_date='01.08.2013' and end_date='04.08.2013' In this example start_date and end_date are string literals. If your start_date and end_date are of date datatype, the TO_DATE() function won't be needed:
select count(*) as num_of_weekdays
from ( select level as dnum
from dual
connect by (to_date(end_date, 'dd.mm.yyyy') -
to_date(start_date, 'dd.mm.yyyy') + 1) - level >= 0) s
where to_char(sysdate + dnum, 'DY',
'NLS_DATE_LANGUAGE=AMERICAN') not in ('SUN', 'SAT')
Result:
num_of_weekdays
--------------
2
Checkout my complete working function code and explanation at
https://sqljana.wordpress.com/2017/03/16/oracle-calculating-business-days-between-two-dates-in-oracle/
Once you have created the function just use the function as part of the SELECT statement and pass in the two date columns for Start and End dates like this:
SELECT Begin_Date, End_Date, fn_GetBusinessDaysInterval(Begin_Date, End_Date) AS BusinessDays FROM YOURTABLE;

sql add year statement

I have sysdate in one column and I want to add two years in another. I would not like to use sysdate + 365
Is there any other way?
select add_months(sysdate, 12) from dual
SELECT your_date_column + interval '2' year
FROM dual