Convert Varchar column to datetime - sql

I have two columns as below. ColumnA is a varchar. 9bd is an assigned number, 10 is fiscal year, 07 is month, and the rest is unique id. ColumnB is datetime.
ColumnA ColumnB
9db1007000001 8/7/2011
I would like to seperate from ColumnA into a Month column (datetime) and a Year column (datetime).
Desired result from ColumnA:
Column Month Column Year
7 2010
OR
7 10
I can seperate ColumnB into Month column and Year column. Here is my attempted SQL script.
SELECT
ColumnA,
DATEPART(mm, (ColumnB)) as Month,
DATEPART(yy, (ColumnB)) as YEAR
FROM MY TABLE
Can someone please help? I did search within this website and found similar question but my attempted script produces error
--Conversion failed when converting datetime from character string.
SELECT
CAST(SUBSTRING(ColumnB, 5, 2) + SUBSTRING(ColumnB, 3, 2) AS DATETIME) Month_Year
FROM MY TABLE
BTW, this DATEPART(yy, (ColumnB)) function returns 2011. How can it return 11 instead?
Or should I submit another question?

the conversion from a string to datetime requires the string in a proper format, which depends on your DB settings too.
for the second question about getting the last two digits, I suggest to use modulo instead of subtraction - you never know whether it's 2000 or 1900, unless you are 100% it's 2000
a quick example:
SELECT SUBSTRING(columnA, 4, 2) AS FiscalMonth,
SUBSTRING(columnA, 6, 2) AS FiscalYear,
CAST(SUBSTRING(columnA, 6, 2) + '-01-' + SUBSTRING(columnA, 4, 2) AS DATETIME) Fiscal, -- in format of YY-dd-MM, but this really depends on your settings
DATEPART(MM, ColumnB) AS [Month],
DATEPART(YY, ColumnB) % 100 AS [Year]
FROM yourTable;

Related

Two columns with dates (one any day of week, another one WEEK ENDING DATE (SATURDAY) BASED ON 1st column)

I have such a situation.
I need to have 2 columns 1) Is just pull data from a table (just as it is) r.[RCLDTE] (Day of week)
and 2 column) I need to basically look at the first column and make it Saturday of that week.
SELECT r.[RCLDTE] AS 'Day of Week'
,r.[RCLDTE] AS 'Week Ending Day (Saturday)'
Before what I was doing at similar projects I just used this code and added to WHERE statement.
WHERE CONVERT(DATE, CONVERT(CHAR(8), r.[RCLDTE] )) = cast(DATEADD(dd, DATEPART(DW,GETDATE())*-1, GETDATE()) as date)
This code was changing the dates column to Saturday.
However, here I have a different situation. I need 2 columns 1) as it is and 2) where dates will be Saturdays of the week from r.[RCLDTE] column , as a result from the way how I understand I cannot use WHERE statement because it will affect both columns.
Does someone know how I can leave 1st column as it is and 2nd a column of Saturday.
Please let me know.
Thanks.
To avoid issues when someone changes either DATEFIRST or LANGUAGE settings, you can use this. Also, given that you are storing dates in a numeric column for some reason (you really should provide feedback to whoever owns the system so they can fix it), we have to first try to convert those values to a date (they may not all be valid, which is one of the problems with using the wrong data type):
;WITH t AS
(
SELECT *, ProperDate = CASE WHEN ISDATE(CONVERT(char(8), RCLDTE)) = 1
THEN CONVERT(date, CONVERT(char(8), RCLDTE)) END
FROM dbo.tablename
)
SELECT [Language] = ##language, [Datefirst] = ##datefirst,
RCLDTE = CASE WHEN ProperDate IS NULL THEN RCLDTE END,
[Day of Week] = ProperDate,
[Saturday] = DATEADD
(
DAY,
6 - ((DATEPART(WEEKDAY, ProperDate) + ##DATEFIRST - 1) % 7),
ProperDate
)
FROM t;
Updated db<>fiddle that also demonstrates the handling of garbage data and a version of SQL Server so old that TRY_CONVERT() didn't exist yet (at least 12 years ago).
here is one way :
select
r.RCLDTE AS 'Day of Week'
, dateadd(day, 7 - datepart(weekday, r.RCLDTE) , r.RCLDTE)
from tablename r
db<>fiddle here

Get past 6 months data from a table based on the recent date present in the column

I have a database table which is named as table and there is a column Col which is present in table with datatype varchar. Column Col contains dates in the format MMM-YY.
For example Col has values as :
Col
DEC-21
NOV-21
SEP-20
OCT-19
DEC-21
As, we can see data can be duplicated like DEC-21. I want to extract last 6 months data based on the recent month present in Col. For example, If the DEC-21 is the most recent date(consider, day is not present) and so, I want data from DEC-21 to JUN-21 i.e. 12-21 to 06-21 if we map DEC to 12 and JUN to 06. This Table has many columns and one of the columns is Col which I mentioned above and I have to extract data based on the column Col by using SQL query.
I have written a query as:
SELECT *
FROM table
WHERE CAST(RIGHT(Col,4) AS INT) Between 2020 and 2021
But here I get data between 2020 and 2021. So, By doing some modification in the above query or Is there any other way to get the past 6 months data from the recent date which is in MMM-YYYY format from Col column.
I was writing code in R and I was using dbGetQuery() where I have to pass the SQL query. I have already done this thing after storing it in a dataframe but is there any way to do it directly by sql query ?
Any help would be appreciated.
with data as (
select *,
convert(date, '01-' + dt, 105) as converted_dt,
max(convert(date, '01-' + dt, 105)) over () as last_converted_dt
from T
)
select * from data
where converted_dt >= dateadd(month, -6, last_converted_dt);
The 105 comes from the list of date formats which can be found in the documentation for cast/convert. SQL Server can convert strings like Apr 2021 so a cast like below might also work (if you actually have four-digit years) but it's best to be explicit about the format as I did above.
cast(replace(dt, '-', ' ' as date)
Something like this should work.
SELECT * FROM table where CONVERT(DATE,'01-'+Col) BETWEEN '01-Jun-2021' and '31-Dec-2021'

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

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 )

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