Subtract 4 months from a pair of year/month values - sql

I want to subtract 4 months, the period is defined as year and month:
UPDATE [MAS_YCA].[dbo].[temp_AR_SalesPersonhistory]
SET FiscalYear = year(DATEADD(month,-4,DATEADD(DAY,-1,DATEADD(month,cast(FiscalPeriod as Int),DATEADD(year,cast(FiscalYear as Int)-1900,0))))),
FiscalPeriod = right('00'+cast(month(DATEADD(month,-4,DATEADD(DAY,-1,DATEADD(month,cast(FiscalPeriod as Int),DATEADD(year,cast(FiscalYear as Int)-1900,0))))) as varchar),02)
GO
The error I'm getting is Adding value to a datetime column caused an overflow.
The fields fiscal year and period are both defined as varchar in the datable.

Sounds like you need to check the data in the FiscalYear and FiscalPeriod columns. Most likely, you have an invalid year in the Fiscal year column.
The date range in SQL Server is January 1, 1753, through December 31, 9999. So any year outside this will cause your error.
An easy check (edit, added null and empty string cases):
Select * from [MAS_YCA].[dbo].[temp_AR_SalesPersonhistory]
where cast(FiscalYear as Int) > 9999 or cast(FiscalYear as Int) < 1753
or FiscalYear is NULL or FiscalYear = ''

Related

Combine and convert nvarchar month field + float year field to a single date field

I have a table in SQL Server 2012 with a month column stored as nvarchar(255):
"January", "February", "March"
And another column in this table with year stored separately as float
"2012","2013,"2014".
I do not have a day column so I want to create a combined month date column with the day starting as 1.
So for month and year fields January 2012. I want to show '2012-01-01'
How can I do such and add that into my current table?
I want to find the maximum row for a record in my table for each employee.
so for an [employee #], [month],[year]. what is latest record so for example below:
1. 102, Jan, 2019
2. 102, feb, 2019
I want to only see the second record which is the latest.
SQL Server has pretty flexible conversion to date. So, just convert the columns to a date:
select convert(date, month + ' ' + year)
You can get the maximum as:
select empid, max(convert(date, month + ' ' + year))
from t
group by empid;
If you really like, you can change the format for output purposes. I would advise you to stick with a date, though.
Note: This assumes that your internationalization settings are set to English -- which seems reasonable if you are storing month names in English.
Fix your design! The way you store data makes it really inefficient to interpret it. Here, I think the simplest option is datefromparts() and a 12-branches case expression.
Assuming that the (float) year is stored in column col_year and the (string) month is in col_month:
select t.*,
datefromparts(
cast(col_year as int),
case col_month
when 'January' then 1
when 'February' then 2
...
when 'December' then 12
end,
1
) as date_col
from mytable t

Set a hardcoded day and month for a given year in TSQL

I am working on a small query and would like a little assistance formatting a date
Situation
I am accepting a payment date and based on that date I set the expiration date to 31st March of either this year or the next. So if the payment is made in January, the exp date is 31st March of the current year, if it's made in August, it's the 31st March of the next year.
This is my query.
BEGIN
IF DATEPART(MONTH,#paydate) BETWEEN 1 and 3
UPDATE usrBio
SET ExpDate=DATEPART(YEAR,GETDATE())+'-31'+'-03'
WHERE IDnum =#IDnum
ELSE IF
DATEPART(MONTH,#paydate) BETWEEN 4 and 12
UPDATE usrBio
SET ExpDate=DATEPART(YEAR,GETDATE()+1)+'-31'+'-03'
WHERE IDnum =#IDnum
END
The problem I am having is that I am unsure of how to set the month and day as instead of being concatenating to the year string, it's subtracting from the year date and my result is 1905-06-07 00:00:00.000 where I'm expecting 2017-31-03.
If 2012+, consider DateFromParts()
Example 1
Declare #PayDate date = '2017-08-31'
Select DateFromParts(Year(#PayDate)+IIF(Month(#PayDate)>3,1,0),3,31)
Returns
2018-03-31
----------------------
Example 2
Declare #PayDate date = '2017-03-31'
Select DateFromParts(Year(#PayDate)+IIF(Month(#PayDate)>3,1,0),3,31)
Returns
2017-03-31
**
Edit - For 2008
**
Select DateAdd(YEAR,case when Month(#PayDate)>3 then 1 else 0 end,str(Year(#PayDate),4)+'-03-31')
The problem is you trying year as number instead of string
DEMO
SELECT CAST( DATEPART(YEAR,GETDATE()+1)
AS varchar(5)) +'-03'+'-31'
And you can optimize your logic like this
UPDATE usrBio
SET ExpDate = CAST( CASE WHEN DATEPART(MONTH,#paydate) BETWEEN 1 and 3
THEN DATEPART(YEAR,GETDATE())
WHEN DATEPART(MONTH,#paydate) BETWEEN 4 and 12
THEN DATEPART(YEAR,GETDATE()+1)
END AS varchar(4)
) +'-03'+'-31'

Filter on date stored in integer fields without datetime

I've got two columns, one with a year (e.g. 2013, 2014) and one with a number of the month (e.g. 2, 3, 4).
Is there code that I could use to bring back the previous 12 months from my selected month? So if I selected my year as '2014' and my month as '9', I'd like to bring back the results going back to year '2013' and month '10'.
Is that possible without having a datetime field?
This should be possible. I would do this with "month" arithmetic. For instance, to get all dates since 2013-10, for selected month 2014-09:
select t.*
from table t
where year*12 + month >= 2014*12 + 9 - 12;

convert month name in varchar to date so as to order by month [duplicate]

This question already has answers here:
Convert month name to month number in SQL Server
(14 answers)
Closed 9 years ago.
A table exists which stores month name in the form of string..
I want to order by year and month so as to get proper result.
year(string) Month(string) data
------------ ------------ ----
2012 August bigbox
2012 December samllbox
2013 April samll box
2012 September larg
I want to order by year and month. as in 2012,2013...
Jan,feb,march....
I am aware of the method of
case statement when
Month = 'january' THEN 1
Month - FEB THEN 2
But i do'nt want to use this as the procedure will be too big..
Your best option is to use the proper date type. Otherwise, create a table (inline or physical) to map your string months.
SELECT 1 AS month, 'January' AS strMonth
UNION ALL
SELECT 2, 'February'
UNION ALL
SELECT 3, 'March'
...
SELECT 12, 'December'
Then map this your table. See a demo
SELECT *
FROM TABLE
ORDER BY [year] DESC,
DATEPART(month,[Month] + ' 01 ' + CONVERT(VARCHAR(4),[YEAR]))
The above code will give you what you want , but i would strongly suggest you reconsider your design.
Right now you are reserving a string type field which would be at least 15 characters long. This field does not have any value than for display reasons. You could have a DATETIME field that would be much easier to short by (not having to do calculations there) and if you would like to display the name of the month you could use:
DATENAME ( month, DateField )

Need to create Financial Year entries in Oracle 11g DB

I need a financial year entries based on current or today's date AND time in Oracle11g DB.
Suppose if we consider today's date is 1ST April 2013, then i need the outputs as 01-APR-13 and 31-MAR-14.
Our requirement financial Year considered is from April (the current year) to March (following year).
Based on current datetime...the scenario of output depends on the current date-time which falls in the above said period or duration.
Another example: If we take today's datetime as 28th Dec 2012, then the output is needed as 01-APR-12 and 31-MAR-13.
Please help how to acheive the same in very short format using only SQL.
Consider the below table as
Create table venky (financialYearFrom DATE NOTNULL, financialYearTo DATE NOTNULL);
Something ugly:
SELECT to_date('1-APR-'||(to_char(sysdate,'yyyy')+
(case when to_char(sysdate,'mm')>3
then 0
else -1
end))) AS start_date ,
to_date('31-MAR-'||(to_char(sysdate,'yyyy')+
(case when to_char(sysdate,'mm')>3
then 1
else 0
end))) end_date
FROM dual;
If month > 3 then add a year to 31-MAR(end_of_period), else substract a year to 1-APR (start_of_period).
UPDATE: Something nicer:
select add_months(trunc(add_months(sysdate,-3),'yyyy'),3) as start_date ,
add_months(trunc(add_months(sysdate,-3),'yyyy'),15)-1 as end_date
from dual
Substracting 3 months will send you to the correct start year. Truncating to year and adding 3 months sends you to 1 APR. End_of period is 12 months ahead start minus one day.
create user define function for that here is example for SQL SERVER
find how to do it in oracle (both are same with minor diff in syntax)
CREATE FUNCTION [dbo].[getYear]
(
-- Add the parameters for the function here
#CurDate DATETIME
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #Y int;
SELECT #Y = CASE WHEN MONTH(#CurDate) <= 3 THEN YEAR(#CurDate) - 1 ELSE YEAR(#CurDate) END;
RETURN '01-APR-' + LTRIM(STR(#Y)) + ' and 31-MAR-' + LTRIM(STR(#Y+1));
END
and use it like this
Select dbo.GETYEAR(GETDATE());