Subtract one month from mm/yy in SQL - sql

How can I subtract one month from mm/yy in SQL?
For an example from 02/23 to 01/23.

Since your date format is not the recommended one. But for your scenario, you can use the following query to get your expected result.
Using DATEFROMPARTS() and string functions you can construct as a date and the DATEADD(MONTH, -1, date) will help to subtract one month.
DECLARE #TestTable TABLE (DateVal VARCHAR(5));
INSERT INTO #TestTable (DateVal) VALUES ('02/23'), ('01/23'), ('03/30');
SELECT DateVal,
RIGHT(CONVERT(VARCHAR(8), DATEADD(MONTH, -1, DATEFROMPARTS(RIGHT(DateVal, 2), LEFT(DateVal, 2), '01')), 3), 5) AS Result
FROM #TestTable
Result:
DateVal Result
----------------------
02/23 01/23
01/23 12/22
03/30 02/30
Demo on db<>fiddle

I think you need to use convert() to get a valid date, then dateadd() to subtract 1 month and finally format() to get the date in the string format:
select
format(dateadd(month, -1, convert(date, concat('01/', datecolumnname), 3)), 'MM/yy')
from tablename
See the demo.

This comes with a warning is super ugly but if you want string previous month then string again, maybe convert to date do the dateadd then back to string, horrid!
with cte_d
as
(select '01/23' as stringdate
union
select '12/17' as stringdate
)
select stringdate
,cast(Month(dateadd(month,-1,cast(right(stringdate,2)
+ left(stringdate,2) + '01' as date))) as nvarchar(2))
+'/'+
right(cast(Year(dateadd(month,-1,cast(right(stringdate,2)
+ left(stringdate,2) + '01' as date))) as nvarchar(4)),2) as [NewDate]
from cte_d

Related

Formatting date issue

I have the following query:
SELECT ACCOUNTNUMBER, PROCESSDATE
FROM INVENTORY
Result:
ACCOUNT PROCESSDATE
5646546 11082021
4654646 11082021
The date is in the wrong format.
NOTE: I checked the table design and the PROCESSDATE field seems to be an integer.
What code I have tried:
.-format(PROCESSDATE, 'DD/mm/yyyy') as PROCESSDATE [the result is DD/mm/yyyy in the column)
.-CONVERT(date, CONVERT(varchar(6), PROCESSDATE) + '01') myDate [The result is an error]
.-CONVERT(CHAR(10), PROCESSDATEAS Datetime) as 'MyDateTime' [the result is an error]
Desired output: Obtain PROCESSDATE field as MM/dd/yyyy format.
This is a horrible format. Note that if the day is less than 10, then the length of the integer changes. Arggh!
So, my recommendation is to convert to an 8-character string (with a leading '0' if necessary), then construct a canonical date string ('YYYYMMDD'). And convert to a date:
select convert(date,
right(format(processdate, '00000000'), 4) + substring(format(processdate, '00000000'), 3, 2) +left(format(processdate, '00000000'), 2)
)
You can actually move the format() to a subquery, CTE, or values clause, as in:
select convert(date, right(v.processdate_str, 4) + substring(v.processdate_str, 3, 2) +left(v.processdate_str, 2))
from inventory i cross apply
(values (format(i.processdate, '00000000'))
) v(processdate_str)
Here is a db<>fiddle.
You could use DATEFROMPARTS to parse the parts and then format 101 to put in MM/DD/YYYY format. Something like this
SELECT ACCOUNTNUMBER,
PROCESSDATE,
calc.dt,
convert(varchar(12), calc.dt, 101) vc_with_date_format
FROM (values (5646546, 11082021),
(5646546, 11082021))
INVENTORY(ACCOUNTNUMBER, PROCESSDATE)
cross apply (values (datefromparts(right(PROCESSDATE, 4),
substring(cast(PROCESSDATE as char(8)),3,2),
left(PROCESSDATE, 2)))) calc(dt);
[EDIT] Without the virtual table (which was for demo only)
SELECT i.ACCOUNTNUMBER,
i.PROCESSDATE,
calc.dt,
convert(varchar(12), calc.dt, 101) vc_with_date_format
FROM INVENTORY i
cross apply (values (datefromparts(right(i.PROCESSDATE, 4),
substring(cast(i.PROCESSDATE as char(8)),3,2),
left(i.PROCESSDATE, 2)))) calc(dt);
ACCOUNTNUMBER PROCESSDATE dt vc_with_date_format
5646546 11082021 2021-08-11 08/11/2021
5646546 11082021 2021-08-11 08/11/2021
I think your dates are stored as ddMMyyyy in the DB. You can get the desired result by applying the following conversion:
CONVERT(VARCHAR, CONVERT(DATETIME,STUFF(STUFF(PROCESSDATE, 5, 0, '/'), 3, 0, '/'),103), 101)

Convert String to Date/Time in Report Builder query in SQL

I have a column ENTRY_MONTH with dates in it as a string like 11/2017.
I'm trying to convert the column to datetime, preferably the last day of each month, so in the example above would be 11-30-2017.
I've tried
CONVERT(datetime, ENTRY_MONTH, 110)
to no avail. Any advice?
select convert(datetime,right(entrymonth,4) + left(entrymonth,2) + '01')
There are so many ways to do this.
Declare #strDate varchar(10) = '11/2017'
-- concatenate '01/' to get the first date of the month.
-- (it is needed to make a proper date,
-- and not necessary to make it the first date, it can be '17/' as well
Select '01/' + #strDate
Select Convert(DateTime,'01/' + #strDate, 103)
-- the EOMONTH can be used here
Select EOMONTH(Convert(DateTime,'01/' + #strDate, 103))
in your case:
EOMONTH(Convert(DateTime,'01/' + ENTRY_MONTH, 103)
You can try something like:
DECLARE #MyDate varchar(16) = '11/2017'
SELECT DATEADD(d,-1,DATEADD(m,1,CONVERT(datetime, '1/' + #MyDate, 103)))
This uses a European format where the day comes first. Add a month on then take a day off takes you to the end of the month.
If you go step by step converting and formatting, you can do it like this (intermediate results shown in the result, too):
DECLARE #entryMonth VARCHAR(7) = '11/2017';
SELECT
#entryMonth AS "entry month",
FORMAT( -- create a date from the parts you have in the varchar and a 1 for the day
DATEFROMPARTS(RIGHT(#entryMonth, 4), LEFT(#entryMonth, 2), 1),
'MM-dd-yyyy' -- and format it the way you want
) AS "First of month",
FORMAT(
DATEADD(MONTH,
1, -- add a month in order to get the first of next month
FORMAT(
DATEFROMPARTS(RIGHT(#entryMonth, 4), LEFT(#entryMonth, 2), 1),
'MM-dd-yyyy')
),
'MM-dd-yyyy'
) AS "First day next month",
FORMAT(
DATEADD(DAY,
-1, -- subtract a day from the first of next month
DATEADD(MONTH, 1, FORMAT(
DATEFROMPARTS(RIGHT(#entryMonth, 4), LEFT(#entryMonth, 2), 1),
'MM-dd-yyyy'))
),
'MM-dd-yyyy'
) AS "Last day entry month"
entry month First of month First day next month Last day entry month
11/2017 11-01-2017 12-01-2017 11-30-2017

Date conversion for YY-Monthtext to MM/DD/YYYY

Receive date as "19-May" and need to convert it as '05/01/2019', "19-June" to '06/01/2019'.
I have tried various date conversion but it didn't work.
You can try this. Storing date in this format is not a good/suggestion you should use the proper data type which are meant and available for.
You should update the values with proper date time value and then change the data type also. It will save your time & you do not need these conversions every time.
Select Try_Cast('19-May 2019' as Datetime)
OR
Select Try_Cast('19-May' + '2019' as Datetime)
To get the first date of month you can try the below query.
SELECT DATEADD(month, DATEDIFF(month, 0, Try_Cast('19-May 2019' as Datetime)), 0) AS StartOfMonth
Edit
To get the first date of month as per the given data in string, you can use the below query.
declare #dateinStr varchar(20) = '19-May'
Select try_cast('01-' + Replace(#dateinStr, LEFT(#dateinStr, 3), '') + LEFT(#dateinStr, 2) as Datetime) as Date
Here is the demo.
I suppose the months will be 3 chars only, if so then
Select s,
try_Cast(concat(right(s, 3), ' 2019') as Datetime)
from
(
values
('19-May'),
('19-Jun')
) t(s);
If the months is really comes like "June" & "August" then
select s,
try_cast(concat(substring(s, charindex('-',s)+1, 3), ' 2019') as date)
from
(
values
('19-May'),
('19-June'),
('15-August')
) t(s);
If you need to format it as mm/dd/yyyy then use 101 style.
You can do :
SELECT DATEADD(DAY, 1, EOMONTH(CONVERT(DATE, Dates + '-2019'), -1))
FROM ( VALUES ('19-May'), ('19-June')
) t(Dates);

Subtract substring days from date

I'm trying to come up with a Select statement that would return the DATE column minus the number of days in the DAYS column.
This is the query I tried:
SELECT
DATEADD(DAY, -+(REPLACE(ISNULL(DAYS,0), 'DAYS', '')), DATE)
FROM
T
It throws an error
Operand data type varchar is invalid for minus operator
dateadd(day, -1*convert(int, coalesce(replace([DAYS], ' days', ''),'0')), [DATE])
Something like
DECLARE
#Days VARCHAR(25) = '23 DAYS',
#Date DATE = '2018-10-23';
SELECT DATEADD(Day, - CAST(REPLACE(#Days , 'DAYS', '') AS INT), #Date )
If you are using SQL Server 2012+
SELECT DATEADD(Day, - ISNULL(TRY_CAST(REPLACE(#Days , 'DAYS', '') AS INT), 0), #Date )
I think you need to get the number, cast it to integer as negative and use dateadd like below:
SELECT dateadd(DAY,cast('-'+substring([DAYS], 1,charindex(' ',[DAYS])) as int),[DATE])
FROM T
You can use this:
Use CHARINDEX to get the number of days and convert to int
and then minus it from date column
select DATEADD(DAY,-CAST(SUBSTRING(days,1,CHARINDEX(' ',days)) AS INT),DATE),* from #table
The DATEADD function expects an integer for its second parameter argument.
By REPLACING 'DAYS' with an empty string, you are still left with a varchar containing a number and the blank space that was between that number and the word "DAYS".
RTRIM this result and CAST it as an Integer, and you should be good to go.
Oh, and you also need to put ,DATE inside the DATEADD()'s parenthesis.

how to Select getdate () in yyyy/M format

I want to select getdate() in the format yyyy/M. I tried to write a query
SELECT FORMAT(GETDATE(), 'yyyy/M')
but it is throwing an error.
I am a beginner in SQL. How do I get the yyyy/m format if there is only single digit month? E.g. the query should return 2016/1 when there is only one digit month (it should not return 2016/01) and should return 2016/10 when the month has two digits
How about getting the YEAR and MONTH part of the date and just concatenate them:
SELECT
CAST(DATEPART(YEAR, GETDATE()) AS VARCHAR(4)) + '/' +
CAST(DATEPART(MONTH, GETDATE()) AS VARCHAR(2))
Try this:
SELECT FORMAT(GETDATE(),'yyyy/MM')
SELECT FORMAT(CAST('2015-11-15' AS smalldatetime),'yyyy/M'),
FORMAT(CAST('2015-01-15' AS smalldatetime),'yyyy/M')
Gives:
2015/11 | 2015/1
SELECT CONVERT(VARCHAR(7), GETDATE(), 111) AS [YYYY/MM]
OR
SELECT CONVERT(VARCHAR(7), GETDATE(), 111)