Rounding before converting to varchar - sql

For presentations sake I have a value that I want to show to only two decimal places before converting to varchar
select '£' + cast(round(amount,2) as varchar (10))
This works fine and would display the result as, say, £300.00. However the 'amount' also needs to be divided by 100 as part of the query. When I add that in to the code...
select '£' + cast(round(amount/100,2) as varchar (10))
..it displays as £3.000000. Is there any way to remove the extra 0s so only two are shown after the decimal point?

Just use format():
select '£' + format(amount, 2)
This also adds in commas, which seems desirable.
If you don't want the commas, then don't use round(), cast to a decimal type:
select '£' + cast(cast(round(amount, 2) as decimal(10, 2)) as varchar(10))
round() does change the value, but it doesn't change the storage mechanism. The cast( . .. as varchar) doesn't know -- or care -- how many significant values are in the result.
EDIT (for SQL Server):
Instead of format() you can use the str() function:
select '£' + ltrim(str(amount, 10, 2))
Or the last method of converting to a decimal before the conversion.

What is the datatype of amount column? cast the round part into float
select '£' + cast(round(cast(8375.8734/100 as float),2) as varchar (100));
Result is
£83.76
Also this should done in the front end application and not in sql

Related

How to Cast values to decimal in Hive

This is example of the column "Amount" i am working on. I need to remove all '+' and '-' and all leading zeros, then convert to decimal. There are also cases when there is only zeros present and i am not sure what is the best approach for it. Is there a better solution? Please help on this.
Amount
-0000211
+0000101
+0000000
+0000013
CAST(CAST(CAST(Amount as INT) AS varchar(8)) as decimal(8,2)) from payment_table;
use abs() to remove +/- and 0, and then use cast() to cast to decimal.
select CAST( ABS(Amount) as DECIMAL(8,2)) as ret_Amount -- this will return 211.00

Change the numeric format into 'AM/PM' format in CONCAT / MAX (sql)

I need to change the numeric format into 'AM/PM' format in CONCAT function (I use SSMS v 18.5.1)
Here is my formula. RCLDTE - is a date and RCLTIM is time. I basically need to leave RCLDTE as it is and change the format of RCLTIM from numeric to date and convert to AM/PM format.
How the column looks right now
Format of RCLTIM - numeric
CONCAT(c.RCLDTE, ' & ', MAX(c.RCLTIM)) AS 'Date & Time',
When I tried to use CONVERT function as I tend to use, it raised an error.
CONCAT(c.RCLDTE, ' & ', CONVERT(varchar(15),CAST( MAX(c.RCLTIM) AS TIME),100))
Error
Explicit conversion from data type numeric to time is not allowed.
The number for the date can be concatenated to the number for the time stuffed with colons. So that it can be converted to a DATETIME.
And by using FORMAT the DATETIME can be put in a specific format.
(But use CONVERT if it has the format.)
Test snippet
declare #test table (
ID INT IDENTITY PRIMARY KEY,
RCLDTE int,
RCLTIM int
);
insert into #test (RCLDTE, RCLTIM) values
(20220119, 215250)
, (20220304, 070809)
;
select
FORMAT(TRY_CAST(CONCAT(c.RCLDTE, ' ', STUFF(STUFF(FORMAT(MAX(c.RCLTIM),'000000'),5,0,':'),3,0,':')) AS DATETIME)
, 'd/M/yyyy hh:mm:ss tt') AS [Date & Time]
from #test c
group by RCLDTE;
Date & Time
19/1/2022 09:52:50 PM
4/3/2022 07:08:09 AM
Test on db<>fiddle here
What you're attempting to do is very fragile, but I presume your source system gives you few options.
Converting like this has potential problems with DST & the language in use at the time of running.
Your question lost some of the detail regarding formats, so I can't see the time type you are using, but it looks like a decimal again.
Essentially, you need to put the the numerics in a string and then into datetime columns, but to get there you have to match a string conversion format the sqlserver.
Fortunately you are not far off the us format default.
Something like this will get you a date field, you can then amend the output format if you really need 12hr rather than 24hr.
SET LANGUAGE us_english
DECLARE #rcldte NUMERIC, #rcltim numeric
SET #rcldte=20220119
SET #rcltim = 015250
SELECT
CONVERT(DATETIME, CAST (#rcldte AS VARCHAR)+ ' ' +
LEFT( left('000000', 6-LEN(CAST ( #rcltim AS VARCHAR)))+CAST ( #rcltim AS VARCHAR),2)
+ ':' + substring( left('000000', 6-LEN(CAST ( #rcltim AS VARCHAR)))+CAST ( #rcltim AS VARCHAR),3,2)
+ ':' + RIGHT( left('000000', 6-LEN(CAST ( #rcltim AS VARCHAR)))+CAST ( #rcltim AS VARCHAR),2))
Which will give you:
(No column name)
2022-01-19 01:52:50.000
It's rather ugly though.
If you can guarantee the hours are zero padded then you could remove the complexity associated with that.
And if you're really going to use it then split into proper UDFs...
DECLARE #RCLDTE CHAR(8) = '20220119';
DECLARE #RCLTIM CHAR(6) = '215250';
select CONVERT(VARCHAR(21), (cast(#RCLDTE as DATETIME) + cast(substring(#RCLTIM,1,2)+':'+substring(#RCLTIM,3,2)+':'+substring(#RCLTIM,5,2) as DATEtime) ), 22);
output: 01/19/22 9:52:60 PM
For different formats of the DATETIME, see the docs of the CONVERT function:
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15
NOTE: When specifying another format the value 21 in VARCHAR(21) might need a change...

How to format % and in 2 decimal points?

How do I code format the return data in 2 decimals and with percentage format like 100.00% or 67.39% instead of 100.000000 or 67.391304?
SUM(qa.scripting1+qa.conduct1+qa.conduct2+qa.conduct3)*100.0/46 as 'C%'
I tried ROUND() but I got the error stating that the round function requires 2 to 3 arguments?
ROUND(SUM(qa.scripting1+qa.conduct1+qa.conduct2+qa.conduct3)*100.0/46) as 'C%'
Thanks!
You can convert to a decimal your original value:
CONVERT(VARCHAR(20), CONVERT(DECIMAL(18,2), SUM(qa.scripting1+qa.conduct1+qa.conduct2+qa.conduct3)*100.0/46) ) + '%' as 'C%'
The first number in the decimal represents the number of digits in the number including decimal places, and the second number represents the number of decimal places.
You should pass number of decimals in second parameter to round function. For formating you can cast number to money and then cast to varchar:
select cast(cast(ROUND(SUM(123.12321)*100.0/46, 2) as money) as varchar) + '%'
Using Round and Cast will work. First round to 2 decimal places then convert to a decimal with 2 places to truncate the excess zeros.
select cast(Round(yourValue, 2) as decimal(18,2))
Sql Fiddle
You can use Format function
select FORMAT(100.0000, 'N' , 'en-us')
returns 100.00
and
select FORMAT(67.391304, 'N' , 'en-us')
returns 67.39
EDIT
In version below 2012 you can do this
SELECT CAST(67.391304 AS NUMERIC(10, 2))
returns 67.39
You can just do:
select FORMAT(0.391304, '##0.00%')
But keep in mind that it implicitly multiplies by 100, so the above will display as 39.13%.

SQL Server 2005 money format

I have been using SQL Server 2005, and I need to store some columns in database in Money format.
But SQL Server stores them like this --> 0000.0000, but I only want 2 digits after the decimal point ---> 0000.00
Do I have to control this in the program or there is a way to change this format in SQL Server 2005 ?
Thanks in advance
I would normally do these formatting stuffs in the front end. But if you still have to do it within the DB layer itself then make use of ROUND function.
SELECT CAST(ROUND(1234.1234, 2) AS MONEY)
Would also suggest you to check out the Performance storage comparison between Money & Decimal post written by Aaron Bertrand: https://sqlblog.org/2008/04/27/performance-storage-comparisons-money-vs-decimal
Money Vs Decimal Vs Float Decision Flowchart (Extract from SQLCAT.com):
Source: http://sqlcat.com/sqlcat/b/technicalnotes/archive/2008/09/25/the-many-benefits-of-money-data-type.aspx
Use Round() function. Returns a numeric value, rounded to the specified length or precision.
More here.
Round(value,2,1)
Second parameter specifies precision to be two decimal places.
Third parameter with value one specifies truncate rather than round off.
try this it works for SQL Server 2008 and below (2012 have already a FORMAT() function that you can use)
this will only works for data type Money and SmallMoney
declare #v money -- or smallmoney
set #v = 1000.0123
select convert(varchar(25), #v, 0)
select convert(varchar(25), #v, 1)
select convert(varchar(25), #v, 2)
select convert(varchar(25), #v, 126)
select '$' + convert(varchar(25), #v, 0)
select '$' + convert(varchar(25), #v, 1)
select '$' + convert(varchar(25), #v, 2)
select '$' + convert(varchar(25), #v, 126)
Hope this help!

SQL IsNumeric Returns True but SQL Reports 'Conversion Failed'

Assuming the following data:
Column1 (data type: varchar(50))
--------
11.6
-1
1,000
10"
Non-Numeric String
I have a query, which is pulling data from this column and would like to determine if the value is a number, then return it as such in my query. So I am doing the following
SELECT CASE
WHEN IsNumeric(Replace(Column1, '"', '')) = 1 THEN Replace(Column1, '"', '')
ELSE 0
END AS NumericValue
SQL is reporting back:
Conversion failed when converting the varchar value '11.6' to data type int.
Why? I have also tried to force cast this:
SELECT CASE
WHEN IsNumeric(Replace(Column1, '"', '')) = 1 THEN cast(Replace(Column1, '"', '') AS float)
ELSE 0
END AS NumericValue
And I got:
Error converting data type varchar to float.
You need to replace comma with a period:
CAST(REPLACE(column, ',', '.') AS FLOAT)
SQL Server outputs decimal separator defined with locale, but does not unterstand anything but a period in CASTs to numeric types.
First convert the string to money, then covert it to any other numeric format since money type gives a true numeric string always. You will never see an error then.
Try the following in your query, and you'll know what I am talking about. Both will return 2345.5656. The Money datatype is rounded to 4 decimal places, and hence the casting causes rounding to 4 decimal places.
SELECT CAST('2,345.56556' as money), CAST('$2,345.56556' as money)
Cast( cast('2,344' as money) as float) will work perfectly or
cast( cast('2,344' as money) as decimal(7,2)) will also work.
Even cast(CAST('$2,345.56556' as money) as int ) will work perfectly rounding it to nearest integer.
There are many issues with SQL isnumeric. For example:
select isnumeric('1e5')
This will return 1 but in many languages if you try to convert it to a number it will fail. A better approach is to create your own user defined function with the parameters you need to check for:
http://www.tek-tips.com/faqs.cfm?fid=6423
ISNUMERIC returns 1 when the input expression evaluates to a valid integer, floating point number, money or decimal type;
So the problem is it is a valid number but not a valid int.
Kyle,
I think this solves the problem. The problem lies in the fact that the ELSE clause initializes your result to be an INTEGER. By making an explicit typecast to FLOAT and adding the suggestion of Quassnoi, it seems to work.
DECLARE #MyTable TABLE (Column1 VARCHAR(50))
INSERT INTO #MyTable VALUES('11.6')
INSERT INTO #MyTable VALUES('-1')
INSERT INTO #MyTable VALUES('1,000')
INSERT INTO #MyTable VALUES('10" ')
INSERT INTO #MyTable VALUES('Non-Numeric String')
SELECT CASE WHEN ISNUMERIC(REPLACE(Column1,'"','')) = 1 THEN REPLACE(REPLACE(Column1,'"',''), ',', '.') ELSE CAST(0 AS FLOAT) END
FROM #MyTable
Regards,
Lieven
IsNumeric(' ') also returns 1, but then CAST as int blows up. Brendan above says write your own function. He is correct.
This solution does not work in all cases (specifically numbers with money and/or thousand separators). Concatenate an exponent representation to the end of the number which is represented by a string...ISNUMERIC() works fine from there. Examples below:
-- CURRENT ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'); --1
SELECT ISNUMERIC ('-1'); --1
SELECT ISNUMERIC('1,000'); --1
SELECT ISNUMERIC('10"'); --0
SELECT ISNUMERIC('$10'); --1
-- NEW ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'+'e+00'); --1
SELECT ISNUMERIC ('-1'+'e+00'); --1
SELECT ISNUMERIC('1,000'+'e+00'); --0
SELECT ISNUMERIC('10"'+'e+00'); --0
SELECT ISNUMERIC('$10'+'e+00'); --0
This, at the very least, standardizes the format for using the REPLACE() function.
I have just meet this issue.
You can try this solution if you don't mind about limitation of decimal length.
CONVERT(numeric, CONVERT(money, '.'))
NOTE:
It is supported in SQL Server 2008 or above.
Money range is : -922,337,203,685,477.5808 to 922,337,203,685,477.5807 - four decimals.