Create date column using year and month columns to yyyymmdd - sql

I have a year column that contains things like 2013, 2012, etc and a month column that displays 1-12. I need to use these columns to create a date that always pulls the last day of the month that the year and month represents as yyyymmdd. For example, if year = 2018 and Month = 3, I need the date to display as 20180331. The year and month fields are numeric. I am using SQL Server 2014 Management Studio Any ideas on how to do this?

You could shoe horn it this way:
select REPLACE(CAST(EOMONTH(DATEFROMPARTS(2018,2,1)) as varchar(20)), '-','')

I was able to find a formula that works, although the answer above is smaller in code and may be a more efficient way to accomplish the same thing, which I can test out. Here is the code that I was able to get to work for those interested.
CONVERT(VARCHAR(10),eomonth(CAST(CAST(FV_RPT_EMPLOYEECENSUS_ASOF.HRYEAR AS VARCHAR(4)) + RIGHT('0' + CAST(FV_RPT_EMPLOYEECENSUS_ASOF.HRPERIOD AS VARCHAR(2)), 2) + RIGHT('0' + CAST(01 AS VARCHAR(2)), 2) AS DATE)),112)

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

Fetch month name based on various dates in table

I have one table that contains BillDate column i.e. Bill Dates for various customers. The bill date range from September 1 to September 30. Based on the billdate, I want to fetch Month name in format "Sep-19" (19 being year 2019)
The issue is that from next month, the BillDate will have records for both September and October 2019.
For Oct 2019, the bill month that I want to fetch is "Oct-19" as I will create a report based on data present for bills in October month.
How to fetch bill month based on data that changes every month?
One method uses format():
select format(BillDate, 'MMM-yy')
A more old-fashioned method constructs the string:
select left(datename(month, BillDate), 3) + '-' + right(datename(year), BillDate), 2)
FORMAT is an awful function for this, it's horrifically slow. I highly recommend CONVERT and a style code, along with some string manipulation.
REPLACE(STUFF(CONVERT(varchar(11),BillDate,106),1,3,''),' ','-')
You can try this:
SELECT REPLACE(RIGHT(CONVERT(VARCHAR(20), BillDate, 106), 8), ' ', '-')
For Getting Most Recent Data you can try this
SELECT REPLACE(RIGHT(CONVERT(VARCHAR(20), BillDate, 106), 8), ' ', '-') AS 'YourColumnName' FROM TableName
ORDER BY BillDate DESC
For Testing Purpose:-
SELECT REPLACE(RIGHT(CONVERT(VARCHAR(20), GETDATE(), 106), 8), ' ', '-') AS 'CurrentDate'
Output:-
CurrentDate
-----------
Oct-2019
Use the format function to convert the date in your format. And then you can use the where function to get the results for current month (oct 2019).
Note: Format is small and nice function if you're using to build this report query for small data. But if you're working with relatively large datasets I would recommend convert as format would have affect on performance.
Select *
From
(select your_field1, your_field2, format(BillDate, 'MMM-yy') as Current_Date from your_table) as alias_table
Where [Current_Date] = format(GETDATE(), 'MMM-yy');
In SQL you cannot use alias columns names within the same query that is why I have used a subquery in paranthesis to force SQL to handle where before select.

Finding the last day of the week

I have a table with a bunch of dates (option maturity dates to be precise). I need to query this database to find the last day of a specific week that is stored in the table.
All I will be given to query this table is the year, the month and the specific week. And based on this I need to find the date that is stored in the table that matches this.
I've created the following query to find this specific date March 28 2013
SELECT M_SETNAME, M_LABEL, M_MAT FROM OM_MAT_DBF
WHERE M_SETNAME = 'IMM_OSET '
AND MONTH(M_MAT) = 3
AND YEAR(M_MAT) = 2013
AND ((DATEPART(day,M_MAT)-1)/7 + 1) = 5
Do you guys have any idea of how I can change the last condition so that March 28th will be considered the 5th week of the month and not the 4th week as it is currently doing.
You can also use DATEPART to get the number of the week (in the year), but then, you could also get the 1st of each month, and take the week too so you can have: WEEK OF MY DATE - WEEK OF FIRST DAY FOR THIS MONTH + 1.
Here you have an example...
DECLARE #Dt datetime
SELECT #Dt='03-28-2013'
SELECT DATEPART( wk, #Dt) - DATEPART( wk, Convert(Date,Convert(varchar(4),YEAR(#Dt))
+ '-' + Convert(varchar(2), MONTH(#Dt))
+ '-' + Convert(varchar(2), 1))) + 1
EDIT: Also, looking at your code, you could add the CEILING. If the result == 2.7, it means it passed the 2nd week, however, it gets rounded to 2 when it should actually be 3.
If you add the CEILING and the CONVERT to decimal should work..
SELECT MONTH(#Dt),
YEAR(#Dt),
((CEILING(Convert(decimal,DATEPART(day,#Dt)-1)/7)) + 1)

How do I do a comparison with just a month and year, not a complete date?

I need to write a stored procedure to allow someone to search a db. However, all I get are ints for month and year. And the db has month and year fields. But I can't figure out how to set up the comparison.
Ex: I get March 2008 and June 2010.
I need to searhc the database for records where the date, as specified by the month and year fields, are between thoese two dates.
Edit
Given two Date inputs, how do I find all records that fall between those dates? Each record only has integers representing year and month.
Previous solutions should work, but unfortunately they prevent using index on year and month columns.
You will probaly have to wirte it the hard way:
SELECT *
FROM records
WHERE Year > #StartYear
OR ( Year = #StartYear
AND Month >= #StartMonth)
/*(ommited end date check, it is same)*/
Another possibility is to add computed date column to source table
Storing date this way is suspicios and probably incorrect from DB design point of view. Consider storing date in date column and (if you really need it) adding computed columns for year and month.
Assuming you are provided Date variables called #StartDate and #EndDate in SQL Server:
SELECT
*
FROM
MyTable
WHERE
-- yields "200901 between 200801 and 201104" on inputs 01-01-2008, 04-01-2011
Convert(VarChar(10), MyTable.Year) + Replace(Str(MyTable.Month, 2), ' ', '0')
BETWEEN
Convert(VarChar(10), YEAR(#StartDate)) + Replace(Str(MONTH(#StartDate), 2), ' ', '0')
AND
Convert(VarChar(10), YEAR(#EndDate)) + Replace(Str(MONTH(#EndDate), 2), ' ', '0')
References
Simple Left-Padding for Int to String Conversion - Inspired Replace(Str(MyTable.Month, 2), ' ' , '0')
TSQL Between
An unconventional approach:
select * from sometable
where YourYear * 100 + YourMonth
between #SomeStartYear * 100 + #SomeStartMonth and #SomeendYear * 100 + #SomeEndMonth

Create a date from Credit Card expire in MMYY format

I need to convert a credit card expire field from MMYY to a date field I can use in a MS SQL query so I can compute when credit cards are expiring in the future. Basically, I need to go from MMYY to MM/DD/YYYY, where the day part could just be '01' (the first of the month).
I'm looking for credit cards that are expiring next month from a database. The problem I'm running into is when next month is the first month of the next year.
Here's the code I have for determining expired card:
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 < YEAR(GETDATE()))
or
(
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 = YEAR(GETDATE()))
AND
(CAST(SUBSTRING(CCExpire,1,2) as int) < MONTH(GETDATE()))
)
And here's the code for cards expiring this month:
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 = YEAR(GETDATE()))
AND
(CAST(SUBSTRING(CCExpire,1,2) as int) = MONTH(GETDATE()))
Now I need code for cards expiring next month...
You're just looking for cards expiring in the next month? Why not just figure out the MMYY string of the month you're searching for, then use that in your predicate:
WHERE CCExpire = (RIGHT('00' + CAST(MONTH(DATEADD(mm, 1, GETDATE())) AS VARCHAR), 2)
+ RIGHT(CAST(YEAR(DATEADD(mm, 1, GETDATE())) AS VARCHAR), 2))
Surely it's just
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 = YEAR(GETDATE()))
AND
(CAST(SUBSTRING(CCExpire,1,2) as int) = MONTH(GETDATE())+1)
note the +1 after the MONTH(GETDATE())
ah - just noticed your "first month of year" problem. Hang on...
You can use:
CCExpire < DATEADD(mm,GETDATE(),1) AND CCExpire > GETDATE()
that way you don't have to worry about the problem of the month wrapping into next year.
Big Edit: only just realised that you don't have a date field - you have a MMDD field. So I reckon, build up the credit card date first, maybe into a parameter to make it easier to see whats going on, using DATEADD and then use that along with the code above to evaluate.
You can convert your MMYY dates using this:
print convert(datetime, str(2000+'10')+'06'+'01')
in this example 10 is the YY and 06 is the MM, so you could use something like:
print CONVERT(datetime, str(2000+SUBSTRING(CCExpire,3,2))+SUBSTRING(CCExpire,1,2)+'01')
Surely it'd be easier to convert the CC's MMYY format to SQL server's preferred date format client-side. That'd let you store it in a normal date field, from which you could then just do normal date math:
DATEADD(month, 1, GETDATE())
would properly return the equivalent date in the next month (and adjusts so that Jan 31 + 1 month = Feb 28)