I want to normalize my SQL Server column before adding to datagridview, I did it in my SQL query. But I have a problem.
If the value fully dividing (for example 100/100=1) I don't want to see this value like 1.00000000000000. And if the value is not fully dividing (for example 3/7=0.42857142857), I want to round that value to two digits after rounding (0.43).
This is my code:
string q = "SELECT column1, column2, ((CONVERT(DECIMAL(18, 2), column3) / (SELECT MAX(column3) FROM tablename)) * 100) AS normalizedColumn3
FROM tablename .......;
I need to normalize column 3, it's values before normalize between 1 - 2000000. After normalize, values will be between 0.01 - 100.
Normalize formula:
column 3 = ((column 3 / maximum column 3) * 100)
Thank you for answers...
You'll have a small matter of data-loss if you only want two decimals. You'll need at least 5 decimals for values between 1 and 2,000,000
Example
Declare #YourTable table (Col3 float)
Insert into #YourTable values
(1),(1536),(1000000),(2000000)
Select A.*
,NewVal = convert(decimal(10,2), (Col3*100.0) / ( Select max(Col3) from #YourTable) )
From #YourTable A
Returns
Col3 NewVal
1 0.00 -- At decimal(10,5) you would see 0.00005
1536 0.08
1000000 50.00
2000000 100.00
I believe you can use ROUND ( numeric_expression , length [ ,function ] ) or SELECT ROUND(CAST (# AS decimal (#,#)),#); to round your decimal.
Here is more info on it :https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-2017
Related
I want to display number as percentage as shown below, The column datatype is Varchar
1 100.0%
0.8 80.0%
0.9 90.0%
My approach would be:
create a CTE
convert it to a numeric data type like decimal
multiply the value by 100
convert the value back to varchar and tack on the percentage sign
with tab as
( Select (cast(column1 as decimal(9,1)) *100) as 'newcolumn'
From sample1)
Select cast(newcolumn as varchar(12)) + '%' as 'Percent'
From tab
Original Data:
Select * from sample1
column1
1
0.5
0.2
Output:
Percent
100.0%
50.0%
20.0%
Sample data
DECLARE #numberdata AS TABLE ( Number VARCHAR(100))
INSERT INTO #numberdata
SELECT 1 UNION ALL
SELECT 0.8 UNION ALL
SELECT 0.9
SELECT * FROM #numberdata
We should not save numerical data in string format , if you want get data in the form percentage first cast the number column data from varchar to decimal data type and multiply with 100. Try this below
SELECT Number,
CAST(CAST(Number AS DECIMAL(4,1))*100 AS VARCHAR(10))+'%' AS InPercantage FROM #numberdata
Result
Number InPercantage
--------------------
1.0 100.0%
0.8 80.0%
0.9 90.0%
I have a tsql query that does calculations for percentages, and it calculates fine if the result is > 1, but returns 0 when it is less than 1. My calculation is like so:
create table dbo.#temptable (
total_sold int null,
#_in_ny int null,
percent_in_ny decimal(18,2)null
) on [primary]
insert into dbo.#temptable
select count(t.booknum) as totalsold, t.#_in_ny, 100 * t.#_in_ny / count(t.booknum)
from mytable t
That gives me:
total ny sales %sales in ny
650 4 0 ---- this should show up as 0.61 since 4 is .61% of 650
The problem is that SQL Server does integer division. The simplest solution is to use 100.0 as the constant:
insert into dbo.#temptable
select count(t.booknum) as totalsold, t.#_in_ny,
t.#_in_ny * 100.0 / count(t.booknum)
from mytable t
t.#_in_ny / count(t.booknum) - You are doing integer division here. Convert both of these to floats or decimals.
insert into dbo.#temptable
select count(t.booknum) as totalsold, t.#_in_ny, 100 * CONVERT(float,t.#_in_ny) / CONVERT(float, count(t.booknum))
from mytable t
EDIT: See Gordon's answer as well. While either solution works, his is certainly a bit more eloquent than mine.
I have the rows below, and i want to access prior row and divide its value by current row. For every row, i need to calculate the Vi value, this Vi value is equal to Vi-1/Vi which means that:
Given the table
Table T
id value out
1 100
2 200
3 10
4 50
I want to generate these values
V1 = 100
V2= 100/200 = 0.5
V3 = 0.5/10 = 0.05
V4 = 0.05/50 = 0.001
So at the end i want the following output:
id value out
1 100 100
2 200 0.5
3 10 0.05
4 50 0.001
I tried using the aggregate function SUM with OVER(), but i do not know how to solve this problem as i need to divide and not sum the value
SELECT id, value, SUM(value) OVER(ORDER BY id ROWS BETWEEN
1 PRECEDING AND 1 PRECEDING ) / value as out
FROM T
Sample data:
CREATE TABLE t(
id INT,
value INT
);
INSERT INTO t VALUES
(1, 100), (2, 200), (3, 10), (4, 50);
Unfortunately, SQL do not have Product, but it should be simple to use cte. The performance should be not bad if id was indexed
DECLARE #T table (id int identity(1,1) primary key, value int)
INSERT #T VALUES (100), (200), (10), (50)
;WITH cte AS
(
SELECT id, value, CAST(value AS decimal(20,4)) AS out FROM #T WHERE id = 1
UNION ALL SELECT T.id, T.value, CAST(cte.out / T.value AS decimal(20,4)) FROM cte INNER JOIN #T T ON cte.id = T.id - 1
)
SELECT * FROM cte
This an example table and I want to get all negative numbers and minimum positive number (0 included) for per id
declare #tbl table(id INT, value decimal, someData varchar(10))
insert into #tbl
values(1,-3,123),(1,-2,234),(1,-1,345),(1,3,456),(1,4,567),(2,-4,678),(2,-2,789),(2,1,890),(2,2,135),(3,-5,246),(3,10,357)
select * from #tbl where value < 0 union
select id, min(value),someData from #tbl WHERE value > 0 group by id,somedata
I am trying to find a solution by separating minuses and pluses. but because of someData I cannot group by them as I need.
desired result is:
1 -3 123
1 -2 234
1 -1 345
1 3 456
2 -4 678
2 -2 789
2 1 890
3 -5 246
3 10 357
Also its a long working query so I dont want to make double select. Is it possible to make it in one select?
This should work:
;With separated as (
select *,ROW_NUMBER() OVER (PARTITION BY SIGN(value),id ORDER BY value) as rn
from #tbl
)
select * from separated where SIGN(value) < 0 or rn=1
You haven't said what should happen if value is 0 so the above may or may not be correct if your data contains some.
SIGN is a little-used but occasionally useful function in SQL Server, returning -1, 0 or +1 and allowing us to easily partition the groups of numbers into 3 groups.
Using a union to combine the conditions is likely easiest. But to select the row with the minimum positive value requires an sub-query, and the assumption that ID is a unique identifier:
select id,value,somdata from #tbl where value < 0
union
select id,value,somdata from #tbl
where value = (select min(value) from #tbl where value > 0)
(That won't include rows with a zero value, but the question doesn't say which side they should fall.)
Attack it as a single select with an OR where clause, using a subquery to get the minimum positive number:
select * from #tbl
where value < 0
or value = (
select min(value)
from #tbl
where value > 0)
using Window function u can get minimum values. and use UNION to combine the results. TRY THIS..
;WITH CTE
AS (SELECT Row_number() OVER (PARTITION BY ID ORDER BY value) RN, *
FROM #tbl
WHERE value > 0)
SELECT *
FROM #tbl
WHERE value < 0
UNION ALL
SELECT ID,value,someData
FROM CTE
WHERE RN = 1
I have a table with 3 text columns on which I want to do some mathematical calculations.
Table looks like below:
Date Column1 Column2 Column3
-----------------------------------------
2012-08-01 STABLE NEG STABLE
2012-08-02 NEG NEG STABLE
2012-08-03 STABLE STABLE STABLE
Want I want to achieve is
If 2/3 columns is equal to 'STABLE' then it returns 66% i.e. 2/3, as it is in the first row
If 1/3 columns is equal to 'STABLE' then it returns 33% i.e. 1/3, as it is in the second row
If 3/3 columns is equal to 'STABLE' then it returns 100% i.e. 3/3, as it is in the third row
I want to know how I can achieve this using SQL? I'm currently working on MSSQL Server 2008 R2.
I hope my question is clear enough.
So, something like this?
select
((case when col1 = 'Stable' then 1.0 else 0.0 end) +
(case when col2 = 'Stable' then 1.0 else 0.0 end) +
(case when col3 = 'Stable' then 1.0 else 0.0 end)) / 3.0
from yourtable
You can do some formatting on the output, but should be very close to what your looking for.
If those are the only choices for column values:
select ( Len( Column1 ) + Len( Column2 ) + Len( Column3 ) - 9 ) / 3 / 3.0 * 100.0 as 'Percent'
from Foo
The optimizer should handle the constant folding. They are shown for clarity.
Divine Comedy describes a place for people who write code like this.