How to correct this T-SQL syntax to get an output with no decimal places? - sql

I am using SQL Server 2016 and I have the following T-SQL code in my query:
CAST(ROUND([Count of Bookings] * 100.0 / SUM([Count of Bookings]) OVER (PARTITION BY [Market Final], [PropertyCode]), 0) AS NVARCHAR(15)) + '%'
An example of the current output of this code is: 40.000000000000%
I was expecting the output to be: 40%
As a note (I don't know if this is relevant): if I change the number in the nvarchar(x) to lower than 15, I get the following error:
Arithmetic overflow error converting expression to data type nvarchar.

Use str() instead of cast():
str(round([Count of Bookings] * 100.0 /
sum([Count of Bookings]) over(PARTITION BY [Market Final], [PropertyCode]
) , 0), 3, 0) + '%'
Actually, I think str() rounds by default (could the documentation be any less clear on this subject?):
str([Count of Bookings] * 100.0 /
sum([Count of Bookings]) over (PARTITION BY [Market Final], [PropertyCode]
), 3, 0) + '%'

The return type of any input of the ROUND() function is depending on the input data type as you can see on MSDN.
This causes your ROUND() to return a data type with a decimal point (in this calculation a float) that you will have to truncate after the conversion to nvarchar (or cast it to an int before).

Related

Convert hex (Current LSN) to decimal converter

how can we convert Log Sequence Number in SQL Server like this 000000dc:00003146:0002 in decimal value?
Not 100% sure what you're expecting (an example would be useful) however the following shows how to convert each part to decimal and reconcatenate. If you are interested in each value separately then remove the concat_ws
with s as (
select [Current LSN], Replace([Current LSN],':','.') lsn from sys.fn_dblog(null,null)
)
select [Current LSN],
Concat_Ws(':',
Convert(int,Convert(varbinary,Concat('0x',ParseName(lsn,3)),1)),
Convert(int,Convert(varbinary,Concat('0x',ParseName(lsn,2)),1)),
Convert(int,Convert(varbinary,Concat('0x',ParseName(lsn,1)),1))
)
from s
I would like to get a result like 22000000042100001 which is 00000016:000001a5:0001 in decimal value
The value you are showing overflows a bigint however as a string representation you can tweak it slightly:
with s as (
select Replace('00000016:000001a5:0001',':','.') lsn
)
select
Concat (
Convert(bigint,Convert(varbinary,Concat('0x',ParseName(lsn,3)),1)) * 1000000,
Convert(int,Convert(varbinary,Concat('0x',ParseName(lsn,2)),1)) * 10000,
Convert(int,Convert(varbinary,Concat('0x',ParseName(lsn,1)),1))
)
from s
Result: 2200000042100001

Rounding before converting to varchar

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

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%.

How do i convert minutes to represent hours decimally in sql?

I have Minutes 140. Which in hours and minutes becomes 2:20.
In this case i would love to get 2.33.
What i've tried:
select cast(140/60 as varchar(8)) + '.' + cast((140 % 60) as varchar(8))
Outputs: 2.20
select 140/60
Outputs: 2
select cast(140/60 as decimal(5,2))
Outputs: 2.00
What am i missing?
How do i convert 140 minutes to represent hours decimally?
Sorry about the quick comment, i'll try to explain a little more clearly about this.
By default, Sql will "think" that both your dividend & divisor are INT data type, that's why it returns 2.
If you specify the number with decimal, like this :
select (140.00/60.00)
now the data type is not int any more, and the result is : 2.3333333
So, you will need to convert one of the data type to float, decimal, numeric(n, n) to get the accurate result :
select cast(140 as decimal(5, 2)) / cast(60 as decimal(5, 2))
But you still can just convert only dividend or divisor, like this :
select 140 / cast(60 as decimal(5, 2))
or
select cast(140 as decimal(5, 2)) / 60
they both gave the same result, becasue the result type is the data type of the argument with the higher precedence, in this case, decimal has the higher precedence than int
you can read more here :
Divide
Data Type Precedence
Try this
Select convert(decimal(5,2),convert(float,140)/60)
or
Select cast(140.00/60 as decimal(5,2))

How to cast computed column with correct decimal/$ result

I have the following computed column in sql server 2008
[Total] AS CAST ( ((val1/(1000)) * [val2]) AS DECIMAL(18,2)) PERSISTED,
When val1 = 862500 and val2 = 8, the computed value = 6896.00
I need it to be decimal/money where (862500/1000) * 8 = 6900.00 (not 6896.00).
BOL says:
Caution: When you use the +, -, *, /, or % arithmetic operators to
perform implicit or explicit conversion of int, smallint, tinyint, or
bigint constant values to the float, real, decimal or numeric data
types, the rules that SQL Server applies when it calculates the data
type and precision of the expression results differ depending on
whether the query is autoparameterized or not.
Therefore, similar expressions in queries can sometimes produce
different results. When a query is not autoparameterized, the constant
value is first converted to numeric, whose precision is just large
enough to hold the value of the constant, before converting to the
specified data type. For example, the constant value 1 is converted to
numeric (1, 0), and the constant value 250 is converted to numeric (3,
0).
When a query is autoparameterized, the constant value is always
converted to numeric (10, 0) before converting to the final data type.
When the / operator is involved, not only can the result type's
precision differ among similar queries, but the result value can
differ also. For example, the result value of an autoparameterized
query that includes the expression SELECT CAST (1.0 / 7 AS float) will
differ from the result value of the same query that is not
autoparameterized, because the results of the autoparameterized query
will be truncated to fit into the numeric (10, 0) data type. For more
information about parameterized queries, see Simple Parameterization.
So, you need to convert [val1], 1000 and [val2] to float types:
[Total] AS CAST ( ((CAST ([val1] as float)/CAST (1000 as float)) * CAST ([val2] as float)) AS DECIMAL(18,2)) PERSISTED
I came up with this:
SELECT (cast(862500 as float)/cast(1000 as float) ) * 8
returns 6900
To make it 2 decimal places....
SELECT cast((cast(862500 as float)/cast(1000 as float) ) * 8 as decimal(18,2))
returns 6900.00
Your specific case:
[Total] AS CAST ( ((cast(val1 as float)/(1000)) * cast([val2] as float)) AS DECIMAL(18,2)) PERSISTED,