first date and last date of month from month and year - sql

How to get first date and last date of month in oracle by giving input parameter as month.
For eg. if i give input month as 'Jan' and Year as '2016' it should give first date and last date of the month.

You can use TRUNC for that:
First day:
TRUNC(your_date, 'MM')
Last day:
ADD_MONTHS(TRUNC(your_date, 'MM'), 1) - 1
You basically TRUNC the month to its first day, add one month to get the first day of the next month, and then go back a day.
If you do not have a date in the month but only the month and the year you can simply use the first of each month to construct a date:
TO_DATE('1.' || your_month || '.' || your_year, 'DD.MM.YYYY')
ADD_MONTHS(TO_DATE('1.' || your_month || '.' || your_year, 'DD.MM.YYYY'), 1) - 1

You can use the TRUNC and LAST_DAY functions for this purpose.
select TRUNC(d,'MM'), LAST_DAY(d)
from (select to_date('01-2016','MM-YYYY') as d from dual);
01-JAN-2016 00:00:00 31-JAN-2016 00:00:00

Related

DB2 query to fetch last month of data. on current month

Every month I have to fetch records for the previous month from a Db2 database. How can I write a Db2 query to fetch the last month of data without hard-coding the date range? For example, when run in December 2021, the query would return records dated between '2021-11-01' AND '2021-11-30', and those dates would change dynamically when I run the same query a month later.
It's easy to can precompute the date range in a cte and then use it in the main query. Assuming your table t has a ts column to filter by, you can do:
with
r as (
select
to_date(year(c) || '-' || month(c) || '-01' , 'YYYY-MM-DD') as e,
to_date(year(p) || '-' || month(p) || '-01' , 'YYYY-MM-DD') as b
from (
select current date as c, current date - 1 month as p from sysibm.sysdummy1
) x
)
select *
from t
cross join r
where t.ts >= r.b and t.ts < r.e
See example at db<>fiddle.
There are a few ways to describe the prior month as a date range in a Db2 SQL query. Some datetime SQL functions are not available on Db2 for z/OS, but even then you can still use date arithmetic and the LAST_DAY() function.
First day of last month: LAST_DAY(CURRENT DATE - 2 MONTHS) + 1 DAY
Last day of last month: LAST_DAY(CURRENT DATE - 1 MONTH)
First day of this month: LAST_DAY(CURRENT DATE - 1 MONTH) + 1 DAY
Inclusive-exclusive example (preferred approach):
SELECT ... WHERE someDateTimeColumn >= LAST_DAY(CURRENT DATE - 2 MONTHS) + 1 DAY
AND someDateTimeColumn < LAST_DAY(CURRENT DATE - 1 MONTH) + 1 DAY
Inclusive-inclusive example (calling the DATE() function will prevent implicit type conversion which could skip some some qualifying rows):
SELECT ... WHERE someDateTimeColumn >= LAST_DAY(CURRENT DATE - 2 MONTHS) + 1 DAY
AND DATE(someDateTimeColumn) <= LAST_DAY(CURRENT DATE - 1 MONTH)
If you're querying Db2 for LUW v11.1 or newer, you can also call the THIS_MONTH() function to get the first day of an input month.
First day of last month: THIS_MONTH(CURRENT DATE - 1 MONTH)
First day of this month: THIS_MONTH(CURRENT DATE)
Inclusive-exclusive example:
SELECT ... WHERE someDateTimeColumn >= THIS_MONTH(CURRENT DATE - 1 MONTH)
AND someDateTimeColumn < THIS_MONTH(CURRENT DATE)

how to check a date is in current financial year

I am trying to check a condition if given date is in current financial year i.e april to march. but not getting any idea how to do
code
select nvl(Count(1), 0)+1 from ASET where IPE='O' and irt in (SELECT EXTRACT (YEAR FROM ADD_MONTHS (SYSDATE, -3))
|| '-'
|| EXTRACT (YEAR FROM ADD_MONTHS (SYSDATE, 9))
FROM DUAL)
irt is date 01-09-2020.
I think the simplest approach is to offset the date column and sysdate by 3 months, and compare the year part:
where to_char(add_months(irt, -3), 'yyyy') = to_char(add_months(sysdate, -3), 'yyyy')

getting last day from next month

I need to get last day from next month in this select.
select (last_day(month from :date+1)||'.'||
(extract(month from :date)+1)||'.'||
extract(year from :date))
from dual;
Everything is ok with month and year but I have a problem with last day function.
Using (extract(month from :date)+1) will not work for a date in December as you will end up with a 13th month. Similarly, extract(year from :date) will get you the current year - which may not be correct if you are looking for the last day of the next month from December and the result should be the January of the following year.
You do not need to extract all the fields separately, you can do it all in a single statement:
SELECT TO_CHAR(
LAST_DAY( ADD_MONTHS( :date, 1 ) ),
'DD.MM.YYYY'
)
FROM DUAL

select Last date of next year in oracle

How to get the last date of next year in oracle sql?
Last date of next year is one day before the first day of the year after next. So you should be able to get it by adding 24 months to the first day of THIS year, and then subtracting one day. Like this:
select sysdate, add_months(trunc(sysdate, 'y'), 24) - 1 as last_day_next_year from dual;
SYSDATE LAST_DAY_NEXT_YEAR
---------- ------------------
2016-08-04 2017-12-31
1 row selected.
Try this:
select add_months(to_date('31-DEC-' || to_char(current_date, 'YYYY')),12) from dual;
Something like...
Select last_day(add_months(sysdate, 12 + (12- to_number(to_char(sysdate, 'mm'))))) from dual;

Date conversion issue in sql

I would like to convert the payment day field from AUTO_TABLE into a day of the month. The payment day is stored in string format and the first nine days are stored as single character. I want to append a '0' string before the payment day for day 1-9 and convert the resulting string into 'DD'. The query worked for two months, but Oracle throws an error stating "invalid Month" when I attempt to convert the string into a date. How can I convert the payment day into two character decimals and proceed to concatenate day with the current month and year? Thanks for your help.
Select case when Payment_Day <> to_char(sysdate, 'dd')
then Payment_Day
end as Payment_day,
Payment_Day2,
trunc(sysdate) - 8 as DateEdit2,
trunc(sysdate) - 15 DateEdit1
From(
Select case when Payment_Day2 > trunc(sysdate)
then Payment_day2 - 31
else Payment_Day2 end as Payment_Day2,
Payment_Day, theSysdate as theSysdate
From(
Select distinct to_date(Payment_Day2, 'MM/DD/YYYY') as Payment_Day2,
Payment_Day, theSysdate
From(
Select thePIDM,
to_char(DateEdit, 'MM') || '/' || to_char(Payment_Day, '00') || '/' || to_char(sysdate, 'YYYY') as Payment_Day2,
to_char(Payment_Day) as Payment_Day, Trunc(theSysdate) theSysdate
From (
Select distinct PIDM as thePIDM,
to_char(Payment_Day) as Payment_Day,
trunc(sysdate) as DateEdit,
to_char(sysdate, 'DD') as theSysdate
from AUTO_TABLE
Group by PIDM, to_char(Payment_Day)
)
)
Order by Payment_Day2
)
Order by Payment_Day2
)
The query worked for two months. Yes you were lucky the run it in July and August, both having 31 days.
The problem is in the line
to_char(DateEdit, 'MM') || '/' || to_char(Payment_Day, '00') || '/' || to_char(sysdate, 'YYYY') as Payment_Day2,
which mix the payment_day with the current month (from sysdate). This leads to invalid dates such as 09/ 31/2015.
The remedy is in reducing the payment day to the last day of the current month
-- instead of
-- to_char(Payment_Day) as Payment_Day,
-- limit the payment day to the last day of the current month
to_char(least(to_number(Payment_Day),CAST(to_char(LAST_DAY(sysdate),'dd') AS INT))) as Payment_Day,