I have a decimal column in a table defined as decimal(8,3). I would like to include this column in a Select statement, convert it to a Varchar and only display two decimal places. I can't seem to find the right combination of options to do this because everything I try still produces three decimal places.
Here's one way:
create table #work
(
something decimal(8,3) not null
)
insert #work values ( 0 )
insert #work values ( 12345.6789 )
insert #work values ( 3.1415926 )
insert #work values ( 45 )
insert #work values ( 9876.123456 )
insert #work values ( -12.5678 )
select convert(varchar,convert(decimal(8,2),something))
from #work
if you want it right-aligned, something like this should do you:
select str(something,8,2) from #work
If you are using SQL Server 2012, 2014 or newer, use the Format Function instead:
select Format( decimalColumnName ,'FormatString','en-US' )
Review the Microsoft topic and .NET format syntax for how to define the format string.
An example for this question would be:
select Format( MyDecimalColumn ,'N','en-US' )
You might need to convert the decimal to money (or decimal(8,2)) to get that exact formatting. The convert method can take a third parameter that controls the formatting style:
convert(varchar, cast(price as money)) 12345.67
convert(varchar, cast(price as money), 0) 12345.67
convert(varchar, cast(price as money), 1) 12,345.67
I think CAST(ROUND(yourColumn,2) as varchar) should do the job.
But why do you want to do this presentational formatting in T-SQL?
Hope this will help you
Cast(columnName as Numeric(10,2))
or
Cast(#s as decimal(10,2))
I am not getting why you want to cast to varchar?.If you cast to varchar again convert back to decimail for two decimal points
Hope this will help .
DECLARE #emp_cond nvarchar(Max) =' ',#LOCATION_ID NUMERIC(18,0)
SET#LOCATION_ID=10110000000
IF CAST(#LOCATION_ID AS VARCHAR(18))<>' '
BEGIN
SELECT #emp_cond= #emp_cond + N' AND
CM.STATIC_EMP_INFO.EMP_ID = ' ' '+ CAST(#LOCATION_ID AS VARCHAR(18)) +' ' ' '
END
print #emp_cond
EXEC( #emp_cond)
If the type is decimal(18,0) you need to do a double convert like so:
convert(varchar, convert(decimal, [Bill to Account Number] ))
Otherwise, if you just do convert(varchar) you will get scientific notation.
Related
I have a table with a VARCHAR field called ArrivalDate in format yymmdd (such as 170202).
I am writing a query which converts it to yyyymmdd so it should become 20170202.
However my problem is that I need to cater for the case when inappropriate data is entered into the field, and my query needs to exclude that data. I am achieving this exclusion by using the ISDATE function of TSQL. I also need to select the least recent entry (I'm using order by asc for this).
I am using a variety of converts to write this query, below is my implementation with a sample table and data.
Declare #tmp TABLE (theDates VARCHAR(MAX))
INSERT INTO #tmp VALUES('170202')
SELECT TOP 1 t.theDates
WHEN (ISDATE(t.theDates) = 1) THEN CONVERT( VARCHAR(max),CONVERT(datetime t.theDates), 112)
FROM #tmp t
WHERE (ISDATE(t.theDates) = 1)
ORDER BY CAST(t.theDates as DATE)
However I do not like my approach and it occasionally fails conversion and throws an error with values such as 02/02/02 which breaks the query. Can someone please show me a better way of writing this functionality.
Much appreciated!
You can use TRY_CONVERT and CONVERT to get the correct format and convert the value. Then check that the string is exactly 6 character to prevent other formats from being returned.
SELECT
convert(char(10),convert(date, theDates, 12),112)
FROM
(values('02/02/02'),('170202')) x(theDates)
WHERE
try_convert(date, theDates, 12) is not null
and len(theDates) = 6
You can use cast(#date as datetime)
declare #date varchar(max);
set #date='170202';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
set #date='02/02/02';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
please use create function for check dateformat is Valid or not and use this fun in your query inside cash clouse.
ALTER FUNCTION dbo.f_CheckDate
(#InDate nvarchar(25))
RETURNS DATE
AS
BEGIN
declare #Return DATETIME
select #return = CASE WHEN ISDATE(#InDate) = 1
THEN #InDate
ELSE NULL
END
return #return
END
You could use TRY_CAST or TRY_CONVERT if value cannot be cast it will return NULL.
SELECT
TRY_CAST('20170228' AS DATETIME),
TRY_CAST('170228' AS DATETIME),
TRY_CONVERT(DATETIME, '20170228'),
TRY_CONVERT(DATETIME, '170228')
This works for SQL Server 2012 and newer.
I have a string called Dats which is either of the general appearence xxxx-nnnnn (where x is a character, and n is a number) or nnn-nnnnnn.
I want to return only the numbers.
For this I've tried:
SELECT Distinct dats,
Left(SubString(artikelnr, PatIndex('%[0-9.-]%', artikelnr), 8000), PatIndex('%[^0-9.-]%', SubString(artikelnr, PatIndex('%[0-9.-]%', artikelnr), 8000) + 'X')-1)
FROM ThatDatabase
It is almost what I want. It removes the regular characters x, but it does not remove the unicode character -. How can I remove this as well? And also, it seems rather ineffective to have two PatIndex functions for every row, is there a way to avoid this? (This will be used on a big database where the result of this Query will be used as keys).
EDIT: Updated as a new database sometimes contained additional -'s or . together with -.
DECLARE #T as table
(
dats nvarchar(10)
)
INSERT INTO #T VALUES
('111BWA30'),
('115-200-11')
('115-22.4-1')
('10.000.22')
('600F-FFF200')
I wasn't sure if you wanted the numbers before the - char as well, but if you do, here is one way to do it:
Create and populate sample table (Please save us this step in your future questions)
DECLARE #T as table
(
dats nvarchar(10)
)
INSERT INTO #T VALUES
('abcde-1234'),
('23-343')
The query:
SELECT dats,
case when patindex('%[^0-9]-[0-9]%', dats) > 0 then
right(dats, len(dats) - patindex('%-[0-9]%', dats))
else
stuff(dats, charindex('-', dats), 1, '')
end As NumbersOnly
FROM #T
Results:
dats NumbersOnly
abcde-1234 1234
23-343 23343
If you want the only the numbers to the right of the - char, it's simpler:
SELECT dats,
right(dats, len(dats) - patindex('%-[0-9]%', dats)) As RightNumbersOnly
FROM #T
Results:
dats RightNumbersOnly
abcde-1234 1234
23-343 343
If you know which characters you need to remove then use REPLACE function
DECLARE #T as table
(
dats nvarchar(100)
)
INSERT INTO #T
VALUES
('111BWA30'),
('115-200-11'),
('115-22.4-1'),
('10.000.22'),
('600F-FFF200')
SELECT REPLACE(REPLACE(dats, '.', ''), '-', '')
FROM #T
I am inserting table A to table B. The problematic column looks like -$25.2. I first replaced the $ and tried insert. Got this error
Error converting data type nvarchar to float.
I then checked by
SELECT *
FROM B
WHERE ISNUMERIC([Col Name]) <> 1
and no results were returned.
This is odd. It is supposed to return something.
What should I check next?
I also tried something like
CAST(REPLACE([Col Name], '-$', '') AS FLOAT)
Try using this
DECLARE #Text nvarchar(100)
SET #Text = '-$1234.567'
SET #Text = Replace(#Text,'$', '')
Select CONVERT(float, #Text) AS ColumnValue
Select ABS(CONVERT(float, #Text)) AS ColumnValue
While the 'money' data type isn't great for doing calculations, in this scenario you can use it as an intermediary.
declare #a nvarchar(10)
set #a = '-$25.2'
select
#a,
cast(cast(#a as money) as float)
Only use this though if your data only goes to a max of 4 decimal places, otherwise you will lose precision in the conversion.
I have two type of strings in a column.
DECLARE #t table(parameter varchar(100))
INSERT #t values
('It contains eact01' ),
('It contains preact01')
I'm trying to get the strings that contain the word 'eact01'.
My problem is that using the following SELECT, I get also the variables that contain 'preact01', because it contain 'eact01'.
SELECT * FROM #t WHERE parameter LIKE '%eact01%'
How could I get only the row containing 'eact01'?
This should find all combinations, any character not being a letter or a number considerer this as a spit character or a new word.
SELECT *
FROM #t
WHERE
parameter like '%[^0-9a-z]eact01'
or parameter like '%[^0-9a-z]eact01[^0-9a-z]%'
or parameter like 'eact01[^0-9a-z]%'
or parameter = 'eact01'
Try this-
select *
from #t
where
parameter='eact01'
OR parameter like '%[^0-9a-z]eact01%'
OR parameter like 'eact01[^0-9a-z]%'
OR parameter like '%[^0-9a-z]eact01[^0-9a-z]%'
The easiest way is just add space:
SELECT * FROM #t WHERE parameter LIKE '% eact01%' or parameter LIKE 'eact01%'
You need a string splitter for this. Here is one taken from Aaron Bertrand's article:
CREATE FUNCTION dbo.SplitStrings_XML
(
#List NVARCHAR(MAX),
#Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(#List, #Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
Then, you can use EXISTS:
SELECT *
FROM #t
WHERE EXISTS(
SELECT 1
FROM dbo.SplitStrings_XML(parameter, ' ') s
WHERE s.Item = 'eact01'
)
I have a table with a nvarchar column. This column has values for example:
983
294
a343
a3546f
and so on.
I would like to take MAX of this values, but not as text but like from numerics. So in this example numerics are:
983
294
343
3546
And the MAX value is the last one - 3546. How to do this in TSQL on Microsoft SQL?
First install a regular expression function. This article has code you can cut/paste.
Then with RegexReplace (from that article) you can extract digits from a string:
dbo.RegexReplace( '.*?(\d+).*', myField, '$1' )
Then convert this string to a number:
CAST( dbo.RegexReplace( '.*?(\d+).*', myField, '$1' ) AS INT )
Then use this expression inside a MAX() function in a SELECT.
You can try to keep it simple without using Regular Expression
Here is the source
create table #t ( val varchar(100) )
insert #t select 983
insert #t select 294
insert #t select 'a343'
insert #t select 'a3546f';
GO
;with ValueRange as (
select val,
[from] = patindex('%[0-9]%', val),
[to] = case patindex('%[a-z]', val)
when 0 then len(val)
else patindex('%[a-z]', val) - patindex('%[0-9]%', val)
end
from #t
)
select substring(val, [from], [to]) as val
from ValueRange VR
order by cast(substring(val, [from], [to]) as int) desc
CAST() would do the trick, probably.
SELECT MAX(CAST(yourColumn AS int)) AS maxColumns FROM yourTable
Edit.
I didn't read the whole question, as it seems...
– Function to strip out non-numeric chars
ALTER FUNCTION dbo.UDF_ParseNumericChars
(
#string VARCHAR(8000)
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #IncorrectCharLoc SMALLINT
–SET #IncorrectCharLoc = PATINDEX(’%[^0-9A-Za-z]%’, #string)
SET #IncorrectCharLoc = PATINDEX(’%[^0-9.]%’, #string)
WHILE #IncorrectCharLoc > 0
BEGIN
SET #string = STUFF(#string, #IncorrectCharLoc, 1, ”)
SET #IncorrectCharLoc = PATINDEX(’%[^0-9.]%’, #string)
END
SET #string = #string
RETURN #string
END
GO
I picked it from here. (I voted up the reg exp answer though)
you can write a function something like
create FUNCTION [dbo].[getFirstNumeric](
#s VARCHAR(50)
)
RETURNS int AS
BEGIN
set #s = substring(#s,patindex('%[0-9]%',#s),len(#s)-patindex('%[0-9]%',#s) + 1)
if patindex('%[^0-9]%',#s) = 0
return #s
set #s = substring(#s,1,patindex('%[^0-9]%',#s)-1)
return cast(#s as int)
end
and then call
select max(dbo.getFirstNumeric(yourColumn)) from yourTable
if you are using SQL Server 2005 or never you can also use the solution posted by Sung Meister
As far as I know you would need to create a process (or user defined function) to scrub the column, so that you can actually convert it to an INT or other appropriate datatype, then you can take the max of that.
By using user defined function parse the value to an int and then run the select.
SELECT MAX(dbo.parseVarcharToInt(column)) FROM table
SELECT dbo.RegexReplace('[^0-9]', '','a5453b',1, 1)
and RegexReplace installation like Jason Cohen said
This is an old question, I know - but to add to the knowledge base for others...
Assuming all your values have at least 1 number in them:
Select max(convert(int, SubString(VarName, PATINDEX('%[0-9]%',VarName), Len(VarName))))
from ATable
This is my simple answer. You can try it. But it works for fixed removable string value.
select max(cast(SUBSTRING(T.column,3,len(T.column)) as int)) from tablename T