Here is my question:
This is a table named HB06,the data type of "WRTime" is datatime.I want to convert all WRTime to int. For example 2012-11-09 10:52:38.000 will be converted to 20121109105238.
Thank you!
You can't. The value is too large for the int data type. But it does fit into a bigint.
What you can do is to convert it to a string with the desired format, and then cast that ti the bigint type. Using the FORMAT function is IMO more straight forward:
DECLARE #a datetime = '20120304 23:34:12'
SELECT #a
SELECT CAST(FORMAT(#a, 'yyyyMMddhhmmss') AS bigint)
The alternative is to use CONVERT function, which uses less CPU. But there's not direct style that matches that format, so you would then REPLACE() various "litter" characters with nothing. I wouldn't bother with the CONVERT() option unless you work over large data sets.
select
cast(replace(replace(replace(convert(varchar(19), WRTime, 121),':',''),'-',''),' ','') as bigint)
FROM HB06
You can try with below one
select concat(convert(varchar,WRTime,112),datepart(HH,WRTime),
datepart(MINUTE,WRTime),datepart(SS,WRTime)) from HB06
Use below Convert function:
SELECT CONVERT(VARCHAR(100),WRTime,112)+REPLACE(CONVERT(VARCHAR(100),WRTime,108),':','')
FROM HB06
SQL Version 2012 or higher you can use the FORMAT function to get just year and month, then cast it as an int.
On versions prior to 2012 you can do the formatting with the convert function, then cast as int.
declare #WRTime datetime
set #WRTime = '2012-11-09 10:52:38.000'
select cast(format(#WRTime,'yyyyMM') as int) --2012 or higher
OR You can use:
SELECT YEAR(#WRTime)*100 + MONTH(#WRTime);
2012-11-09 10:52:38.000 will be converted to 20121109105238??
Int can't convert this so use "BIGINT"
declare #WRTime datetime
set #WRTime = '2012-11-09 10:52:38.000'
select cast(format(#WRTime,'yyyyMMddHHmmssfff') as bigint) --2012 or higher
Related
I know that the best data type for storing output of the HASHBYTES function is BINARY/VARBINARY, but we want to store it as CHAR as it is suggested by DataVault best practices, moreover not all tolls support keys of BINARY types, for example PowerBI.
So the question is, how to convert it to CHAR? When I do simple CAST/CONVERT I get different output rather than raw output of HASHBYTES function.
SELECT CONVERT(CHAR(32), HASHBYTES('MD5', 'test'))
SELECT CAST(HASHBYTES('MD5', 'test') AS CHAR(32))
SELECT HASHBYTES('MD5', 'test')
Expected value is 098F6BCD4621D373CADE4E832627B4F6 (without 0x) and actual value is kÍF!ÓsÊÞNƒ&'´ö
--convert binary to char without 0x prefix, using style 2
SELECT CONVERT(CHAR(32), HASHBYTES('MD5', 'test'), 2);
I load excel file into sql as varchar(max) and got that Scientific e value which now I try to convert into numeric as I need to do compare that value, and here I'm running into problem.
This is main question: How and to what type I can convert this to compare with whole integer value ?
On the pic You can see how this seen in Excel, even formatted to text it somehow still loaded into varchar(max) not like char string. This can be seen from my test code.
DECLARE #C VARCHAR(MAX) = '1.1001562717e+011', #Nc VARCHAR(MAX) = '110015627174';
SELECT #c, LEN(#c) LenC ,
ISNUMERIC(#c) NumYN
---, CAST(#c AS DECIMAL(38,2)) cDec ---CAST(#c AS NUMERIC) cNum --, CAST(#c AS BIGINT) cInt
WHERE #c LIKE '%[^0-9]%'
AND ISNUMERIC(#c) = 1
To start, ISNUMERIC is a terrible function, it does not give good results; it is often wrong. If you try ISNUMERIC('1.1001562717e+011') you'll notice that you get the value 1, however, CONVERT(numeric(13,1),'1.1001562717e+011') will produce an error. A far better function is TRY_CONVERT (or TRY_CAST), which returns NULL if the conversion fails for the specific data type: TRY_CONVERT(numeric(13,1),'1.1001562717e+011').
Being specific on the data type is actually important here, as ISNUMERIC could be (incorrectly) suggesting that the value could be converted to at least 1 of the numeric data types; but that doesn't mean all of them. For scientific data types the only data type you can convert to is a float/real:
SELECT TRY_CONVERT(numeric(13,1),'1.1001562717e+011') AS Numeric,
TRY_CONVERT(bigint,'1.1001562717e+011') AS int,
TRY_CONVERT(float,'1.1001562717e+011') AS float,
TRY_CONVERT(money,'1.1001562717e+011') AS money;
Notice that only float has a value here. As you want a numeric as the final value, then you'll need to CONVERT the value twice:
CONVERT(numeric(13,1),TRY_CONVERT(float,'1.1001562717e+011'))
Decimal point conversion without rounding to two decimal
My variable is of datatype varchar, so I have to convert it to numeric. But what the thing is my output value is 0.0012499987 and I want the output as 1.24 i.e. without rounding the value.
This is my code
Set #SQLQuery = #SQLQuery + 'CAST((ISNULL(CAST(DI.Coupon AS NUMERIC(18,4)),0) * 100) AS Varchar(50)) AS Coupon,
Here I have to multiply with 100 don't remove that; di.coupon is of type varchar. Keep it in your mind
And the result value also I want as a varchar.
Please someone help me
Sample input / output
0.013923 1.39
You can use CAST
EDIT: I added an ISNULL
DECLARE #N
SET #N = '0.013923'
SELECT CAST(CAST(CAST(ISNULL (#N, 0) AS DECIMAL(38,18)) * 100 AS DECIMAL(18,2)) AS VARCHAR (50))
Probably the easiest is to get the substring of the original column and cast that to numeric. Then it will drop the remaining digits.
In SQL Server, LEFT(column, 4) will do what you want.
But as #HABO pointed out, the in-built function Round() will accept a parameter that truncates the decimal value.
I have got the answer for this. This might help for some people
cast(left(('00122.45678')*100,instr(('00122.45678')* 100,'.','1')+3)as varchar) as stb
Output:
122.456
If you want for 2 decimal without round of then you can add like +2 instead of +3
I've been toying around with T-SQL in an attempt to understand the implicit conversion and overload resolution rules, but somehow it seems to work a bit strange...
Context:
Data type conversion: https://msdn.microsoft.com/en-us/library/ms191530.aspx
Data type precedence: https://msdn.microsoft.com/en-us/library/ms190309.aspx
Abs: https://msdn.microsoft.com/en-us/library/ms189800.aspx
Basically the latter tells you that abs will work on int, float, decimal, etc. So let's see how that works:
declare #foo2 sql_variant;
set #foo2 = abs(4);
select sql_variant_property(#foo2, 'BaseType')
-- result: int. OK, apparently we have an int overload. As expected.
declare #foo2 sql_variant;
set #foo2 = abs(cast(4.0 as float));
select sql_variant_property(#foo2, 'BaseType')
-- result: float. OK, apparently we have a float overload. As expected.
Now, according to the implicit type conversion table, we are allowed to implicitly convert stuff. We're going to check this by converting a varbinary to int, which should happen according to the type precedence rules:
declare #foo varbinary(4);
set #foo = cast(4 as varbinary(4));
select #foo + 2;
-- result: int. OK, as expected.
From this result I would expect the following to work as well:
declare #foo varbinary(4);
set #foo = cast(4 as varbinary(4));
select abs(#foo);
-- result: error: Operand type clash: varbinary is incompatible with float
Stuff I don't understand here (the question):
Why does the implicit conversion pick the 'float' overload of the 'abs'? Is this just a random overload? Or perhaps the overload that's highest in the precedence list (which happens to be 'float')?
Why isn't implicit conversion applied from varbinary -> int? After all, it's a perfectly valid conversion.
From MSDN for Abs:
Arguments
numeric_expression
Is an expression of the exact numeric or approximate numeric data type category.
I guess that calling Abs( varbinary ) would try to convert the varbinary to an exact numeric or approximate numeric data type.
Float is at the top of Data Type Precedence for these types so there is the problem I guess.
UPDATE with my logic
declare #foo varbinary(4);
Declare a varbinary variable.
set #foo = cast( 4 as varbinary(4));
Set to this variable a value by performing an explicit cast from int to varbinary which is perfectly doable.
select sql_variant_property(#foo, 'BaseType')
This shows that the variable is of type varbinary.
select abs(#foo);
Try to run abs on varbinary.
The error message is clear:
Operand type clash: varbinary is incompatible with float
So my guess is that abs is trying to implicit convert varbinary to the first of the Data Type Precedence for exact numeric or approximate numeric data types which is float.
This conversion fails according to CAST and CONVERT chart.
I hope I've got this right! Comments appreciated.
You've found the conversion and precedence MSDN pages so let's take your example apart.
declare #foo varbinary(4);
set #foo = cast(4 as varbinary(4));
Now, what type is foo?
SELECT SQL_VARIANT_PROPERTY(#foo,'BaseType')
--------
varbinary
Good so far so good. But what's 'in' #foo ?
SELECT #foo
----------
0x00000004
Now, ABS() accepts a numeric - a floating point number:
What does 4.00 look like compared to 4? Let's try:
SELECT CONVERT(VARBINARY(MAX), 4.00) ,CONVERT(VARBINARY(MAX), 4);
------------------ -----------------------
0x0302000190010000 0x00000004
See the internal representation of 4.00 is different to 4? It's storing precision, scale and the value whereas your 'int in a varbinary' isn't.
And that's why the conversion fails. ABS() accepts a numeric, your 'wrong format' varbinary cannot be coerced to a numeric as it's not one, it's some other representation - we know it represents an int but SQL Server doesn't.
If you want to add a floating point number to an int that's 'inside' a varbinary, you have to do something like
select CONVERT(INT, #foo) + 2.0
Back to your example:
declare #foo varbinary(max);
set #foo = cast(4.00 as varbinary(max));
SELECT ABS(#foo+2.0)
----------
6.0
4.00 is converted into a varbinary in the correct internal format, and happily coerced into a numeric by the ABS() call. Happy days.
I am getting some trouble converting a string (representing a hexadecimal number) into a bigint. I would also like this to happen inside a function and as effiecient as possible.
Is there anyway of exploiting the built-in functions?
Here is an example of what I want to do:
select convert (bigint, '0000010d1858798c')
The SQL Server 2008 release updated the CONVERT() function to be able to convert hexadecimal values:
select convert(bigint, convert (varbinary(8), '0x0000010d1858798c', 1))
Result:
1155754654092 (decimal) ( == 0x0000010d1858798c )