Concatenated string to date conversion - sql

I am doing something like this,
i have two columns month and year and i want to create a new column which will be in mm/dd/yyy fromat. so in my case mm is month column , yyyy is year column and date is default 01.
update [tablename]
set period= convert(date,month+'/01/'+year)
now i want this period to be in date data type, i am doing:
alter table [tablename]
alter column period date
but it is giving me error that string can't be converted to date.
If anyone could help that will be very helpful.

You have bad data in your table. Since you didn't use the right data type in the first place, you could have anything at all in the month/year columns, since there is no built in validation that month is 1-12 and year is in the valid range of values. For example, someone could have put 99 in month and -213 in year.
Do this:
SELECT period FROM dbo.tablename WHERE ISDATE([month] + '/01/' + [year]) = 0;
This should identify the rows you need to fix. If this returns the whole table, or returns values that you think should be dates, then show a few examples. The syntax in your update doesn't look right (at the very least missing a +) so I'm not sure what you actually ran against your table, but that's not it. Also a much safer format would be:
SET period = [year] + [month] + '01';
This is because what you are using now, mm/dd/yyyy, is not safe from regional, language and dateformat settings. 06/05/2013 could be interpreted as May 6th instead of June 5th, and 11/13/2012 could return an error because SQL Server doesn't know of any 13th month. Loads of details here.
And you don't need to convert it to date first. Just do that with the ALTER - converting it to date does little for you when it's still stored as a string...

Related

Conversion failed when converting date and/or time from character string and pull Quarter/Year from Date

I have a date column that is a bigint, and does not accept nulls. The date format of the values within the column is 20190101. I need a query that tells me the year and quarter. After googling, I found a query that worked. Today it does not work. I receive this error 'Conversion failed when converting date and/or time from character string' on a query. I tracked the cause to the table allowing -1 on some rows. How can I allow for this in my query? I thought I had to convert it to a character to pull out the quarters. I did this using the cast. I changed to a datetime and it said specified scale invalid.
Here is my query:
Select Distinct left(DateKey,4) as Year,
DatePart(QUARTER,cast(cast(DateKey as char(8)) as date)) As Quarter
From WorkersUnitePerformanceFact
Order By Year, Quarter
Both items in the select receive the error.
You're saying that someone has inserted -1 into your column and it's tripping you up. While it's compounding the problem that this data should have been in some kind fo date column originally you can consider filtering out the undesirable values:
Select Distinct left(DateKey,4) as Year,
DatePart(QUARTER,cast(cast(DateKey as char(8)) as date)) As Quarter
From Performance.WorkerPerformanceFact
WHERE DateKey BETWEEN 19700101 and 21991231
Order By Year, Quarter
Adjust the WHERE clause to suit your needs of date range. I picked Jan 1 1970 and 31 dec 2199
But seriously consider changing the data type of the column now (the longer you leave it, the harder it gets..); I promise this won't be the last time this bites you in the ***; next time it will be another problem, like someone inserting 20200230 (there is no 30th of February) and you shouldn't keep trying to filter out the invalid values
The process of conversion to date doesn't have to be an instant one; you can add another DATE type column to the table, start filling it with a trigger from the DATEKEY column, switch apps to using the date column, and then drop the DATEKEY column later (to retain it for a while, populated from the true date column) all over the course of several revisions of the app
Convert the value to a string, then a date:
convert(date, convert(varchar(255), 20190101))
Then you can construct a year/quart using datename():
select (datename(year, convert(date, convert(varchar(255), 20190101))) + 'Q' +
datename(quarter, convert(date, convert(varchar(255), 20190101)))
)

SQL query to bring back list of servers from specific date range

I'm trying to make a query with SQL Server Management Studio 2017 that brings back a count of all the servers with a projected migration date of this year. I have one query made now, but it's still bringing back some servers with dates from years before.
SELECT MONTH(Projected) as [Month], count(*) as [Total]
FROM dbo.tFake
WHERE Projected >='01/01/2019' AND Projected <='12/31/2019
GROUP BY Month(Projected)
ORDER BY [Month]
Date format is mm/dd/yyyy btw. How can I get this query to bring back just servers that are projected for the year 2019?
Going by the assumption that your data type is wrong, the first step is to fix that.
Note, I am assuming that your data only contains dates, and not time (which your query implies). Firstly, you'll need to change the value of all your rows to an convertible value, we'll go with the ISO format yyyyMMdd:
UPDATE dbo.tFake
SET Projected = CONVERT(varchar(8),CONVERT(date,Projected,101),112);
Now that all the rows are a literal string in the format yyyyMMdd we can alter the column:
ALTER TABLE dbo.tFake ALTER COLUMN Projected date;
Now, we can run your query again, but now your data type is correct, you won't have the problem:
SELECT MONTH(Projected) as [Month], count(*) as [Total]
FROM dbo.tFake
WHERE Projected >= '20190101' AND Project < '20200101' --I prefer the >= and < method. This is especially import with date & time data types
GROUP BY Month(Projected)
ORDER BY [Month];
Notice the literal strings I passed are also in the yyyyMMdd format. If you must pass a literal string in the format MMddyyyy you can wrap in a CONVERT with the style code 101: CONVERT(date,'12/31/2019',101). 101 means the US style date (CAST and CONVERT (Transact-SQL).
Remember, this solution assumes you have date only values, and not date and time values. If you do (have date and time values) you'll want to use an appropriate date and time data type and use the ISO8601 style, instead of the ISO style.

LEFT Function in SQL Server returns no results

I am trying to place data corresponding to a certain month into a temp table from an SQL database.
DROP TABLE
#ComPAIR_Alliance_Table
SELECT
IMOno
,period
,[service]
,alliances
INTO
#ComPAIR_Alliance_Table
FROM
com_COMPAIR.dbo.Data_BlueWaterCapacity_US_2
WHERE
LEFT(period, 7) = '2015-03'
SELECT
*
FROM #ComPAIR_Alliance_Table
The period field is in the following format: 2015-03-29 00:00:00.000
However, my code just returns an empty temp table with the right column names but no rows (even though I know for sure rows with that date exist in my table). I have already made sure that the period column is indeed a string by using is.numeric.
Could someone please help me out with what the problem could be?
Thanks!
If it is a date/datetime/datetime2 then you can compare it with 2015-03 like:
WHERE period >= '2015-03-01'
AND preiod < DATEADD(MONTH, 1, '2015-03-01')
In case there is confusion:
The above will match all March 2015 dates such as 2015-03-31, 2015-03-31 23:59:59 and 2015-03-31 23:59:59.9999999
The above is sargable: the DATEADD part does not depend on the table rows
Guessing Period is a date. If it is, stop treating it like a varchar, it isn't one. If you want values from March 2015 then do:
WHERE period >= '20150301'
AND period < '20150401'
LEFT is doing some weird stuff, because LEFT causes an implicit cast to String from Date. You can see this question for more information, but you're getting exactly what you told SQL to get - a join on rows where the left 7 characters of period equal '2015-03' which will not happen, since you're liking comparing against something like 'Jan 01'
The LEFT function needs to implicitly convert your datetime column to a varchar value to do it's work. SQL Server is choosing the varchar format of the date based on it's internationalization settings. On my server, its Mar 29 2015 12:00AM, and LEFT yields Mar 29. That's why it's not equal to 2015-03.
You should treat your column as a datetime and then perform the comparison using a valid datetime comparison, like this :
WHERE period BETWEEN '1/1/2015' AND '1/31/2015'
the date is stored as a date type. You may want to try
where convert(varchar(20), period,121)
which would convert it to string...

Insert only Month and Year date to SQL table

I am using MS SQLServer and trying to insert a month/year combination to a table like this:
INSERT INTO MyTable VALUES (1111, 'item_name', '9/1998')
apparently, the above command cannot work since
Conversion failed when converting date and/or time from character string.
Because 9/1998 is a bad format. I want to fix this and this column of the table will show something like:
9/1998
12/1998
(other records with month/year format)
...
Can someone help me with this?
thank you
SQL Server only supports full dates (day, month, and year) or datetimes, as you can see over on the MSDN data type list: http://msdn.microsoft.com/en-us/library/ff848733(v=sql.105).aspx
You can use a date value with a bogus day or store the value as a string, but there's no native type that just stores month/year pairs.
I see this is an old post but my recent tests confirm that storing Date or splitting the year and month to two columns (year smallint, month tinyint) results in the overall same size.
The difference will be visible when you actually need to parse the date to the filter you need (year/month).
Let me know what do you think of this solution! :)
Kind regards
You can just use "01" for the day:
INSERT INTO MyTable VALUES (1111, 'item_name', '19980901')
You can:
1) Change the column type to varchar
2) Take the supplied value and convert it to a proper format that sql server will accept before inserting, and format it back to 'M/YYYY' format when you pull the data: SELECT MONTH([myDate]) + '/' + YEAR([myDate]) ...
You may want to consider what use you will have for your data. At the moment, you're only concerned with capturing and displaying the data. However, going forward, you may need to perform date calculations on it (ie, compare the difference between two records). Because of this and also since you're about two-thirds of the way there, you might as well convert this field to a Date type. Your presentation layer can then be delegated with the task of displaying it appropriately as "MM/yyyy", a function which is available to just about any programming language or reporting platform you may be using.
if you want use date type, you should format value:
declare #a date
SELECT #a='2000-01-01'
select RIGHT( convert (varchar , #a, 103), 7) AS 'mm/yyyy'
if you want make query like SELECT * FROM...
you should use varchar instead date type.

Storing just Month and Year in SQL Server 2008?

Is it possible to save the month/year in SQL Server 2008 with a regular datetime? I don't need a time stamp and the column is going to store unique mo/yr combinations (i.e. 10-11, 11-11, 12-11, etc,.).
Any recommendations?
Without knowing the intended use, it is not possible to advise correctly. However, storing month and year is easily done in at least three ways:
use a date field, but always store into it the first day of the month at midnight; then always custom format the date field for display
add integer year and month fields, and populate them by splitting a date
add an integer field where you encode it as year * 100 + month or some other useful scheme
Sql Server will store the datetime data in its entirety (year-month-day hour:min:sec.milliSec) no matter what.
When you store your dates, you can make the day the 1st of the month. Just format the dates how you want when you do your queries.
http://www.sql-server-helper.com/tips/date-formats.aspx
From SQLServer 2008 and onwards:
Save as a Date column and add the following check constraint to make sure the value is always the first of the month:
datepart(month, MyDate)<>datepart(month,dateadd(day, -1, MyDate))
You cant only store year and month in a DateTime column. Well, what you can do is default the rest of the values. ie: 2011.10.1.1 , 2011.11.1.1 like that.
Or you can store it as string.
SELECT RIGHT(CONVERT(VARCHAR(10), GETDATE(), 105), 7) AS [MM-YYYY]
You should try this