Percentage in SQL Server - sql

I want to find the percentage between two columns and I tried this :
select
(count(id)* 100.0 /(select count(id) FROM db.table where log = '40')) as percentage
from db.table;
And the result is this:
418659.800405426477
Why the output number is like that?
Also is there any way to make it look better and help end users to understand the percentage?

The output is like that because of the rules that SQL Server uses when doing arithmetic on numbers -- the precision and scale are rather details (note that 1.0 is a numeric constant).
The explanation for this is in the documentation. Note that even I don't bother trying to understand the rules for division.
I just want to point out that you can simplify the query:
select avg(case when log = '40' then 100.0 else 0 end) as percentage
from db.table;
This only scans the table once, so it should be faster. But it should produce a similar result.
If you want a given scale/precision then use round(), floor(), ceil(), str() or convert to a numeric.

Related

Division to output calculation value

Is there a different way in which I can wrap or write the calculation in the query below so that it divides properly besides using round (100.0 * ...) ?
SELECT ROUND(100.0 * COUNT(DISTINCT c.user_id) / COUNT(DISTINCT b.user_id)) AS browse_to_checkout_percent
Thanks!
I'm assuming what you mean by not dividing properly is the fact you're getting unexpected results due to dividing integers. When SQL does math on integers it returns an integer as a result. This means any decimal result is cut off.
So take the query
SELECT 50/100
You would expect a result of 0.5 however since .5 is not an integer you get a result of 0
Likewise with
SELECT 101/100
You would expect a result of 1.01 but you get a result of 1.
COUNT returns an integer so when you do division between the two integers the result is the same as above.
What you need to do with your query is to cast or convert what count returns as another data type. Which datatype you choose depends on a few factors but for what you are doing I would say float will do.
SELECT CAST(COUNT(DISTINCT c.user_id) as FLOAT) / CAST(COUNT(DISTINCT b.user_id) as FLOAT) AS browse_to_checkout_percent
For simplicity I've removed ROUND but you can add that in as needed.
For more info you can see this blog post.

Calculate conversion rate in SQL

The code below calculates the conversion rate of a dataset. The code relevant to this question is in line 13. When I calculate the conversion rate, I divide the total number of purchases made on the website by the total number of users (people who browse) on the website. The output I get is 0.495 but I don't understand why I need the '1.0 *' at the start of line 13 for this to work? I don't know the purpose of this part of the code, but without it the code doesn't work.
Your code is not MySQL code. MySQL does not support square braces around identifiers. One database that does is SQL Server. And it does integer division. So, in SQL Server, 1/2 is 0 rather than 0.5.
The * 1.0 simply converts the integer to something with a decimal point.
Assuming userid is not NULL, this is more easily expressed as:
avg( is_purchase * 1.0 )
forpas and Gordon Linoff are correct that SQL Server performs integer division by default. In future, and for more complex calculations, you can use CTEs or subqueries employing CAST to represent values as floating point values prior to division. E.g., at lines 6-7 you would have:
CAST(p.userid IS NOT NULL AS float) AS is_purchase

SQL Calculation to 2 decimal places

I've got a simple calculation (910 / 28 = 3.5) and I'm trying to perform this in a SQL query:
SELECT CONVERT(DECIMAL(5,2), (910 / 28),2) AS average
But the answer is coming out at 32.00, I'm obviously missing something simple could someone spare a moment to point out my error please?
Thanks,
C
Use this:
SELECT CONVERT(DECIMAL(5,2), (910.0 / 28)) AS average
By taking the quotient as 910.0 / 28 SQL Server will retain decimal precision. Then, make your cast to a decimal with two places. By the way, as far as I know CONVERT typically takes just two parameters when converting a number to decimal.
we can use this query for dynamic value from table:
SELECT CONVERT(DECIMAL(5,2), (cast (910 as decimal))/ 28) AS average
It will give the desire output
Unsure if this applies to your database, but in Trino SQL (a sort of database middleware layer), I find adding a decimal point followed by two zeros to any of two operands in this query (e.g., select 910.00/23 AS average or select 910/23.00 AS average) returns a non-integer value (39.57, instead of 39).
Adding 3 zeros after the decimal (select 910.000/23 AS average) returns a 3-decimal place result (39.565), and so on.
Try this query...
SELECT CAST(910 AS decimal(5,2)) / CAST(28 AS decimal(5,2)) as average
Try use this
select cast(round(910/28.0,2) as numeric(36,2)) AS average

Removing numbers that are negative from SQL query

How do you remove negative numbers from SQL query result.
Example:
Select acquisitionprice-salesprice
From Han.trans
I'm trying to find out the Profit by subtracting two columns from a table and would like to have the negative numbers removed from the result
WHERE salesprice > acquisitionprice
probably is treated as the same as giorgos-betsos commented
WHERE acquisitionprice-salesprice >= 0
but reads a little simpler to me.

using SUM and presenting result as absolute (ABS)

I have both positive and negative numbers (money) in a column and need to:
SUM the total ie. SUM(myColumn) based on if the numbers are +/-
Present the result as an absolute ie. even though the result is -1234 it should be presented as 1234
SQL is not my trade as you probably notice but we've solved most other issues but this one so any help is appriciated. Keep in mind my skill level is very low
You will have to use a combination of the sum and abs aggregate functions in SQL. Since you want the absolute value of the sum, the sum function will need to be called inside the call to abs:
select abs(sum(columnName)) from table
That should work for both SQL Server, MySQL, and Oracle.
Try one (or more) of these
SELECT SUM(moneyColumn) FROM MyTable
SELECT SUM(ABS(moneyColumn) FROM MyTable
SELECT ABS(SUM(moneyColumn) FROM MyTable