I have the query below where the date is hard-coded. My objective is to remove the harcoded date; the query should pull the data for the previous month when it runs.
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and TRUNC(CREATION_DATE) BETWEEN '01-AUG-2012' AND '31-AUG-2012'
Should I use sysdate-15 function for that?
Modifying Ben's query little bit,
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and creation_date between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1))
The trunc() function truncates a date to the specified time period; so trunc(sysdate,'mm') would return the beginning of the current month. You can then use the add_months() function to get the beginning of the previous month, something like this:
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and creation_date >= add_months(trunc(sysdate,'mm'),-1)
and creation_date < trunc(sysdate, 'mm')
As a little side not you're not explicitly converting to a date in your original query. Always do this, either using a date literal, e.g. DATE 2012-08-31, or the to_date() function, for example to_date('2012-08-31','YYYY-MM-DD'). If you don't then you are bound to get this wrong at some point.
You would not use sysdate - 15 as this would provide the date 15 days before the current date, which does not seem to be what you are after. It would also include a time component as you are not using trunc().
Just as a little demonstration of what trunc(<date>,'mm') does:
select sysdate
, case when trunc(sysdate,'mm') > to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as gt
, case when trunc(sysdate,'mm') < to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as lt
, case when trunc(sysdate,'mm') = to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as eq
from dual
;
SYSDATE GT LT EQ
----------------- ---------- ---------- ----------
20120911 19:58:51 1
Data for last month-
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and to_char(CREATION_DATE,'MMYYYY') = to_char(add_months(trunc(sysdate),-1),'MMYYYY');
I believe this would also work:
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where
dealer_name = 'XXXX'
and (creation_date BETWEEN add_months(trunc(sysdate,'mm'),-1) and trunc(sysdate, 'mm'))
It has the advantage of using BETWEEN which is the way the OP used his date selection criteria.
It is working with me in Oracle sql developer
SELECT add_months(trunc(sysdate,'mm'), -1),
last_day(add_months(trunc(sysdate,'mm'), -1))
FROM dual
Getting last nth months data retrieve
SELECT * FROM TABLE_NAME
WHERE DATE_COLUMN BETWEEN '&STARTDATE' AND '&ENDDATE';
Related
I am looking to obtain all data in a table from yesterday in SQL Oracle.
This is simply enough using the WHERE clause, i.e,
SELECT *
FROM My_Data
WHERE TO_DATE(My_Data.Date,'YYYY-MM-DD') = TRUNC(SYSDATE)-1
However if I now need to add more logic where if the day of the query is a Monday (SYSDATE) then obtain data between Friday and Sunday.
Using a between statement is no issue, I'm just not sure if I can include in a where statement given I'm unable to use case statement here.
Thanks
SELECT
*
FROM
My_Data
WHERE
TO_DATE(My_Data.Date,'YYYY-MM-DD')
Between Case When To_Char(SYSDATE, 'DY') = 'MON' Then TRUNC(SYSDATE)-3 ELSE TRUNC(SYSDATE)-1 END
And TRUNC(SYSDATE)-1
You can use the Case expression in Where clause. Regards...
Don't use TO_DATE on a column that is already a date (and if it is a string then don't store dates as strings).
So you are not dependent on the date language session parameter, you can compare the date to the start of the ISO week (which is independent of language) and you can compare on a date range so that Oracle can use an index on your date column:
SELECT *
FROM My_Data
WHERE "DATE" < TRUNC(SYSDATE)
AND "DATE" >= CASE TRUNC(SYSDATE) - TRUNC(SYSDATE, 'IW')
WHEN 0 -- Monday
THEN TRUNC(SYSDATE) - 3
ELSE TRUNC(SYSDATE) - 1
END;
or:
SELECT *
FROM My_Data
WHERE "DATE" < TRUNC(SYSDATE)
AND ( ( TRUNC(SYSDATE) - TRUNC(SYSDATE, 'IW') = 0 AND "DATE" >= TRUNC(SYSDATE) - 3 )
OR "DATE" >= TRUNC(SYSDATE) - 1
);
I came across a problem that in selecting the date for current desired month and year. I tried the 2 statements shown below but failed to execute the query
select to_char(sysdate, 'Month') from income
select * from income where to_char(sysdate,month) = 'feb'
Update
But after researching and learning more in depth on oracle docs website. What i came out with is to use "between" clause. Specifying the first day and last day of the month . Doing so, it will execute the desired month/year
For an example
SELECT column_name
FROM table_name where column_name = (Your own value) AND
column_date >= to_date('01/02/2012', 'dd/mm/yyyy')
and column_date < to_date('01/03/2012', 'dd/mm/yyyy')
I hope this help :)
Are you after something like:
select *
from income
where <date_column> >= to_date('01/05/2019', 'dd/mm/yyyy')
and <date_column> < to_date('01/06/2019', 'dd/mm/yyyy')
(replacing <date_column> with the name of the date column in your income table that you want to filter on)?
I think you can use the following query:
select *
from income
where to_char(<date_column>,'MON-RRRR') = 'MAY-2019';
If you want to pass in a string like 'May 2012', then I would recommend:
select i.*
from income i
where i.datecol >= to_date('May 2012', 'Mon YYYY') and
i.datecol < to_date('May 2012', 'Mon YYYY') + interval '1' month;
That said, I think your application should turn the string value into a date range and you should use that range in your query:
select i.*
from income i
where i.datecol >= :datestart
i.datecol < :dateend + interval '1 day';
I strong encourage you to avoid between with dates, particularly in Oracle. The date data type has a built-in time component, and that can throw off the comparisons.
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
I have a few dates in the YYYY-MM-DD format in the table column. how can I find the nearest date, less than or equal to today?
Normally I would use:
<= (SELECT TO_CHAR (TRUNC (SYSDATE), 'YYYY-MM-DD') from DUAL)
but it will return all values less or equal, and I only want one, the nearest.
Thanks for help.
One method is:
select t.*
from (select t.*
from t
where datecol < sysdate -- trunc(sysdate) ???
order by datecol desc
) t
where rownum = 1;
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;