Why does LEFT(Datetime,1) give me "J"? - sql

So I'm writing a SQL query and it gives me an odd error:
Conversion failed when converting the varchar value 'J' to data type int
I narrowed it down to a LEFT(ProjApprovelDate,1), which for some reason gives me a J.
ProjApprovelDate is a DateTime most of the time, there are a few instances where it is entered incorrectly and is an int instead. To find these I've used (LEFT(ap.ApprovalDate,1) != 1 and LEFT(ap.ApprovalDate,1) != 2). It always begins with either a 1 or 2 when it's in the wrong format. The whole column (in the original table) is int format and shows up with most dates like 20170614, but there are several that show up like 1170614 instead. I'm converting these into the correct format and inserting them all into a new table with this column as DateTime so that it correctly makes them into a date.
When reviewing to make sure that I got them all I found this interesting case where the ones that are already formatted correctly as DateTime give me a J.
So my question is why does taking the first LEFT character of a DateTime give a J for the output?

The implicit conversion is a string, so...
Select cast(getdate() as varchar(25))
,left(getdate(),1)
Returns
(No column name) (No column name)
Jun 14 2017 10:28AM J
Take a peek at https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine
Just for fun, try
Select left(25,1)

Related

Hive converting int column to string and to the target type: date

I have a problem with conversion of datatypes in hiveql. Data type of a column is int, it should be converted to date, but there is no direct conversion function from int to date. At first I converted int into string and it worked as below:
From this moment I based on the second column where I have my data converted to string. When I try to use cast(string as date), then the third column returns only nulls:
What is interesting, there is no problem when the string value to be converted was typed manually by a user:
Does anyone of You know how to deal with this problem?
your method in the comment is quite good.
One more approach using regexp_replace:
select date(regexp_replace(cda_date,'^(\\d{4})(\\d{2})(\\d{2})','$1-$2-$3'))

Date cast to int - why is it wrong?

I've got a question. Why does date CAST to int doesn't work while varchar to int works fine? e.g.
If we declare a variable and run this query it won't work,
declare #dateb datetime
set #dateb = getdate()
select cast(#dateb as int)
while this query will work fine. Why?
select cast(convert(varchar(8),#dateb,112) as int)
date should be 8 numbers.
Your issue comes from a misunderstanding about how SQL Server stores date information. It isn't stored as a readable date, but rather as an integer, or series of integers, that the engine uses to calculate the date in question, and then display in a human friendly way.
The CONVERT function you used above creates a text representation of the date as you're expecting to see it, then converts that representation to an integer (also as you're expecting to see it). The straight conversion from a date data type shows you the integer that SQL Server actually uses to store "today", but that's not what you're expecting.
There's a really good article about it on Robert Sheldon's blog if you're interested in going into more depth.

Cannot convert char to datetime in windows counters table

I have a table in SQL Server 2012 that is populated with Windows perfmon data using the built in Windows processes. The table is automatically created by this process. The problem is the timestamp field is a char but I need a datetime.
I use a view on generated tables to get the data into a usable form and I want to convert the timestamp into a datetime in the view. For some reason anything I try gives me this error:
Conversion failed when converting date and/or time from character string.
I can copy and paste a timestamp value from the table into a convert query and it works, like this:
SELECT convert(datetime, '2018-04-04 00:00:08.022', 121);
or
SELECT cast('2018-04-04 00:00:08.022' as datetime)
But when I try to convert a value directly from the table I get the error:
SELECT convert(datetime, counterDateTime, 121) from counterData
I have ruled out some strange format in row by selecting a specific row with a known correct format but I still get the same error.
What am I missing?
EDIT
Just to reiterate, all the values in the table are in the same format. The table was created automatically by the Windows process that writes perfmon data into the database. I have no control over the format of the data in the table. This is not specific to a row other than the one I am testing, this relates to all rows.
Example:
select counterDateTime from counterData where recordindex = '82331' and counterID = '1'
= 2018-04-04 00:00:08.022
select cast('2018-04-04 00:00:08.022' as datetime)
= 2018-04-04 00:00:08.023
select convert(datetime, '2018-04-04 00:00:08.022', 121)
= 2018-04-04 00:00:08.023
select cast(counterDateTime as datetime) from CounterData where recordIndex = '82331' and counterID = '1'
= Msg 241, Level 16, State 1, Line 109
Conversion failed when converting date and/or time from character string.
Here is an example tutorial for getting the Windows counter data into a database. It's a pretty standard process, there are many more examples online. The interesting tables are CounterData and CounterDetails which I aggregate with a view. It is this in the creation of this view that I would like to do the conversion.
https://logicalread.com/writing-performance-data-sql-server-mo01/#.WuxgzYgvyzU
The CounterDateTime column that I'm interested in is a nullable char of length 24.
I tested by following your instructions and was able to reproduce
SELECT ASCII(RIGHT(CounterDateTime, 1))
FROM dbo.CounterData
Returns 0 which is why I believe your data can't be converted. So basically
the last character is ASCII null.
Workaround is
SELECT CAST(LEFT(CounterDateTime, 23) AS DATETIME)
FROM dbo.CounterData

How can I use data from a string in SQL in a numeric comparison?

I'm a B-grade SQL user, so bear with me. I have a field that is in the NVARCHAR format ("Year"), but all but only about 1 in 1000 records is something other than a number. Yes, this is a ridiculous way to do this, but we receive this database from a customer, and we can't change it.
I want to pull records from the database where the year field is greater than something (say, 2006 or later). I can ignore any record whose year doesn't evaluate to an actual year. We are using SQL server 2014.
I have created an embedded query to convert the data to a "float" field, but for whatever reason, I can't add a where clause with this new floating-point field. I originally tried using a "case-if" but I got the same result.
I'm pulling my hair out, as I'm either missing something really silly, or there's a bug in SQL server. When I look at the field in the little hint, it's showing as a float. When I run this, I get "Error converting data type nvarchar to float."
SELECT VL.Field_A,
VL.FLYear,
VL.Field_B
FROM
(select
Field_A,
cast ([Year] as float) as FLYear,
/* didn't work either*/
/*Convert(float, [Year]) as FLYear, */
Field_B
from CustomerProvidedDatabaseTable
where (Field_A like 'E-%' OR
Field_A like 'F-%')
and
(isnumeric(year)=1)
and
year is not null
) VL
/* this statement is the one it chokes on */
where
VL.FLYear >= 2006.0
If I remove the last "where" clause, it works fine, and the field looks like a number. If I change the last where clause to:
where VL.FLYear like '%2006%'
SQL Server accepts it, though of course it doesn't return me all the records I want.
Try to simplify it and just use TRY_CONVERT(DATETIME, aYearvalue) or TRY_PARSE which will return NULL for values it can't convert and continue to process valid rows. I think you can do away with the where clause as join and just work directly against the column like: (substitute the literal string after datetime with your column)
SET DATEFORMAT mdy;
Select YEAR(try_convert(datetime, '08/01/2017')) as value1
WHERE value1 >=2016;
Try cast/convert to a numeric data type. I have modified the last line of your query to do just that. Take a peek.
SELECT
VL.Field_A,
VL.FLYear,
VL.Field_B
FROM
(select
Field_A,
cast ([Year] as float) as FLYear,
/* didn't work either*/
/*Convert(float, [Year]) as FLYear, */
Field_B
from CustomerProvidedDatabaseTable
where (Field_A like 'E-%' OR
Field_A like 'F-%')
and
(isnumeric(year)=1)
and
year is not null
) VL
/* this statement is the one it chokes on */
where
ISNUMERIC(VL.FLYear) = 1
and
CAST(VL.FLYear AS INT) >= 2006
Check out the following link for cast and convert documentation:
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql
NOTE: ISNUMERIC will return true ( a false positive for a value which has a scientific numerical value, e.g. 1E10, though I don't see this happening from your data).
Another option is TRY_CONVERT.
Documentation on TRY_CONVERT: https://learn.microsoft.com/en-us/sql/t-sql/functions/try-convert-transact-sql
Try using Cast . Use the below link to check in more detail about casting.
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql

Converting a VARCHAR to NUMERIC - No Previous Post Answer Works For Me

I've read many responses to this same question, but none of the answers are working for my latest attempt at CASTing a VARCHAR to NUMERIC:
Cast(Cast(a.VARCHARFIELD as NUMERIC(20,0))as INT)
The error I get is:
The conversion of the varchar value '97264634555 ' overflowed an int column. Maximum integer value exceeded.
Unfortunately, the a.VARCHARFIELD contains accounts like 12345678999 but it also contains text or VARCHAR values like:
BALL
TWIN
12345678999
12345679000
First, you need to determine whether your value is a number. There is no ANSI standard method, but an approximation is to just see if it starts with a number.
Second, int is too small, so I would recommend a decimal format.
So something like this would work on the data you provided:
select (case when VARCHARFIELD between '0' and '99999999999999'
then cast(VARCHARFIELD as decimal(20, 0))
end)
The validation of number can be done much better in any particular database; the form given is sufficient for the data provided in the question.
EDIT:
In SQL Server, a more accurate method would be:
select (case when VARCHARFIELD NOT LIKE '%[^0-9]%'
then cast(VARCHARFIELD as decimal(20, 0))
end)