How do I calculate ratios in SQL?
Most database systems should be able to handle this with something akin to:
Select user_id
, Sum( Case When Result = 'Win' Then 1 Else 0 End ) / Count(*) * 1.0 As WinPercent
From Game
Group By user_id
Order By WinPercent Desc
Btw, I'm assuming you meant to say the win percentage is the total number of wins out of the total number of games. If you really did mean where result <> ''
, then you would need to modify the query like so:
Select user_id
, Sum( Case When Result = 'Win' Then 1 Else 0 End )
/ Sum( Case When Result <> '' Then 1 Else 0 End ) * 1.0 As WinPercent
From Game
Group By user_id
Order By WinPercent Desc
Addition
It was suggested in comments that this is SQL Server specific. It is not. Everything in the above solutions is part of the SQL standard. Whether a given database system implements all of the features required is obviously another matter. So, if we are switching gears to finding a solution that would actually work on most database systems, the one feature that has the most variance in support would likely be the use of the column alias in the Order By. You can achieve the equivalent in a couple of ways but one way that would work on most database systems would be to use a derived table:
Select Z.user_id, Z.WinPercent
From (
Select user_id
, Sum( Case When Result = 'Win' Then 1 Else 0 End )
/ Sum( Case When Result <> '' Then 1 Else 0 End ) * 1.0 As WinPercent
From Game
Group By user_id
) As Z
Order By Z.WinPercent Desc
How to calculate the ratio of records based on values of two columns distinctly with the inner join of another table?
Does this work for you?
I used a case
expression inside the count()
function to count the number of returned products.
The * 1.0
turns the integer division into a decimal division without explicitly casting.
Sample data
CREATE TABLE Products (
ProductID nvarchar(5),
Description nvarchar(50)
);
insert into Products (ProductId, Description) values
('SPO00', 'Sports product 1'),
('SPO01', 'Sports product 2'),
('SPO02', 'Sports product 3'),
('ELE00', 'Electronics product 1'),
('ELE02', 'Electronics product 2');
CREATE TABLE Orders (
ProductID nvarchar(5),
Bought date,
Returned date
);
insert into Orders (ProductID, Bought, Returned) values
('ELE00', '2021-01-05', '2021-01-07'),
('SPO00', '2021-01-01', NULL),
('SPO00', '2021-01-05', '2021-01-08'),
('SPO00', '2021-01-08', NULL),
('SPO01', '2021-01-10', NULL),
('SPO01', '2021-01-15', NULL),
('SPO02', '2021-01-18', '2021-01-20');
Solution
select p.Description,
count(case when o.Returned is not null then 1 end) as ReturnCount,
count(1) TotalCount,
count(case when o.Returned is not null then 1 end) * 1.0 / count(1) as ReturnRatio
from Products p
join Orders o
on o.ProductID = p.ProductID
where p.ProductID like 'SPO%'
and o.Bought >= '2021-01-01'
group by p.Description;
Result
Description ReturnCount TotalCount ReturnRatio
---------------- ----------- ---------- --------------
Sports product 1 1 3 0.333333333333
Sports product 2 0 2 0
Sports product 3 1 1 1
Fiddle to see things in action.
SQL - Group and Aggregation to calculate ratio with respect to total
You can use window functions to compute the view percentage for each offer:
SELECT DISTINCT product, offer,
100.0 * (COUNT(*) OVER (PARTITION BY product, offer)) / (COUNT(*) OVER (PARTITION BY product)) AS ViewPercentage
FROM offers
How to calculate the ratio of this column with 2 rows
For two rows, it's easy.
If you have a big input table, and you want to divide the first row by the second, the third row by the fourth, etc, then you need an ordering column to save yourself.
So, with a two-row table (remember, tables are never ordered), you just rely on the fact that you divide the smaller number by the bigger number.
Here goes:
WITH
-- your input ...
input(counter) AS ( -- count is reserved word, use another name ...
SELECT 101
UNION ALL SELECT 576
)
-- cheat and just divide the smaller by the bigger
-- as "@Gordon Linoff" suggests
-- force a float division by adding a non-integer operand
-- and hard-cast it to DECIMAL(5,2)
SELECT
CAST(
MIN(counter) * 1.00 / MAX(counter)
AS DECIMAL(5,2)
) AS result
FROM input;
-- out result
-- out ----------
-- out 0.18
If, however, you have many rows, and you always need to divide the first row by the second, the third row by the fourth, that is, each odd row in the order by the next even row in the order, then you need an ordering column.
Is your problem just what you suggested, or is there more to it?
How do I calculate the ratio of two values within a SQL group?
Example
Select *
,Ratio = convert(decimal(10,2),
sum(case when [Payment_Mode]='Cash' then [Quantity]+0.0 end) over (Partition By [Item])
/sum(case when [Payment_Mode]='Coupons' then [Quantity] end) over (Partition By [Item])
)
From YourTable
Returns
Item Payment_Mode Quantity Ratio
Apples Cash 20 2.00
Apples Coupons 10 2.00
Grapes Cash 45 15.00
Grapes Coupons 3 15.00
Oranges Cash 300 20.00
Oranges Coupons 15 20.00
EDIT - Another Option is with a simple Join and a conditional aggregation
Select A.*
,B.Ratio
From YourTable A
Join (
Select Item
,Ratio = sum(case when [Payment_Mode]='Cash' then [Quantity]+0.0 end) /NullIF(sum(case when [Payment_Mode]='Coupons' then [Quantity] end),0)
From YourTable
Group By Item
) B on A.Item=B.Item
SQL- calculate ratio and get max ratio with corresponding user and date details
With a recent version of most databases, you could do something like this.
This assumes, as in your data, there's one row per user per day. If you have more rows per user per day, you'll need to provide a little more detail about how to combine them or ignore some rows. You could want to SUM
them. It's tough to know.
WITH cte AS (
select a.user_name, a.date
, a.message_sent / a.message_received AS ratio
, ROW_NUMBER() OVER (PARTITION BY a.date ORDER BY a.message_sent / a.message_received DESC) as rn
from messages a
)
SELECT t.user_name, t.date, t.ratio
FROM cte AS t
WHERE t.rn = 1
;
Note: There's no attempt to handle ties, where more than one user has the same ratio. We could use RANK (or other methods) for that, if your database supports it.
How to calculate ratio of two values in the table for specific key
Try this:
SELECT Number1, Number2,
[Ratio] / (SUM([Ratio]) OVER (PARTITION BY Number1, Number2) * 1.0)
FROM Example
Demo here
Compute ratio of group sizes using SQL
Sounds like you want something like this:
select foo, count(*),
count(*) * 100.0 / sum(count(*)) over () as ratio
from mytable
where bar = 10
group by foo;
This does not guarantee that the value adds up to exactly 100% when rounded. That is a much tricker problem, usually better handled at the application layer. This does produce the "correct" answer, using floating point numbers.
Related Topics
Hive Left Semi Join for 'Not Exists'
Database View Does Not Reflect The Data in The Underying Table
How to Select and Order by Columns Not in Groupy by SQL Statement - Oracle
Composing Database.Esqueleto Queries, Conditional Joins and Counting
Delete ... from ... Where ... In
Sql Server 2012: Add a Linked Server to Postgresql
How to Set Named Parameter on Bigquery Query
Most Efficient Method for Persisting Complex Types with Variable Schemas in Sql
Best Way to Change Clustered Index (Pk) in SQL 2005
Execute Procedure in a Trigger
Group by Week, How to Get Empty Weeks
How to Use Sum for Bit Columns
How to Treat a Union Query as a Sub Query
Error: Subquery Must Return Only One Column