ORACLE SQL - SUM two queries together and a single value - sql

i have looked for a simple example to sum two queries together and get a final output as a single value. I have set up a simple query below to use as an example.
SELECT Count (banana)
FROM FRUIT_BASKET
WHERE CONDITION = 'ROTTEN'
/ -- THEN DIVIDE THIS NUMBER BY
SELECT Count (banana)
FROM FRUIT_BASKET
* 100 -- TO GET A PERCENTAGE
Any help will be great thankyou all

This should do it:
SELECT COUNT(CASE WHEN CONDITION = 'ROTTEN' THEN banana END) * 100 / COUNT(banana)
FROM FRUIT_BASKET

You can do conditional aggregation:
select
count(case when condition = 'ROTTEN' then banana end)
/ count(banana) * 100
from fruit_basket

I like using AVG() for this:
SELECT AVG(CASE WHEN Condition = 'Rotten' THEN 100.0 ELSE 0 END)
FROM FRUIT_BASKET
WHERE banana IS NOT NULL;

I would definitely consider the divide by zero scenario in such case.
So better to use avg aggregate function as suggested by gordon or handle divide by zero scenario by yourself as following:
select
count(case when condition = 'ROTTEN' then banana end)
/ decode(count(banana),0,1) * 100
from fruit_basket
Cheers!!

Related

Proportion request sql

There is a table of accidents and output the share of accidents number 2 to all accidents I wrote this code, but I can not make it work:
select ((select count("ID") from "DTP" where "REASON"=2)/count("REASON"))
from "DTP"
group by "ID"
Something like this (not tested):
select id, count(case reason when 2 then 1 end)/count(*) as proportion
from your_table
-- where ... (if you need to filter, for example by date)
group by id
;
count(*) counts all the rows in a group (that is, all the rows for each separate id). The case expression returns 1 when the reason is 2 and it returns null otherwise; count counts only non-null values, so it will count the rows where the reason is 2.
You can use avg():
select id,
avg(case when reason = 2 then 1.0 else 0 end)
from "DTP"
group by "ID"
This produces the ratio for each id -- based on your sample query. If you only want one row for all the data, then:
select avg(case when reason = 2 then 1.0 else 0 end)
from "DTP";

Find percentage of rows that meet a condition without rounding

I'm trying to find the percentage of rows that meet a specific condition. My query is close but the answer is always rounded to the nearest whole number.
For instance this query below is returning 6 but it should return 6.25. Meaning 6.25% of the rows meet that condition. How would I do this?
select sum(case when name like 'H%' then 1 else 0 end) * 100 / count(*)
from category
Just add a decimal point:
select sum(case when name like 'H%' then 1.0 else 0 end) * 100 / count(*)
from category;
Postgres does integer division.
You can also express this using avg():
select avg(case when name like 'H%' then 100.0 else 0 end)
from category;
The decimal point is not needed. Although Postgres does integer division of integers, it calculates average of integers using decimal points.
And this can be phrase more simply (assuming that name is not NULL):
select avg( (name like 'H%')::int ) * 100
from category;
You need a decimal value, otherwise, since both the numerator and denominator are integers, Postgres does integer division.
But here, I would just use avg() - for which you don't need an integer value:
select avg(case when name like 'H%' then 1 else 0 end) * 100
from category
You're performing integer division, and thus omitting everything right of the decimal point. If you use a floating-point literal 100.0, you should be OK:
select sum(case when name like 'H%' then 1 else 0 end) * 100.0 / count(*)
from category

Oracle (SQL): How to get SQL query syntax

A table (ex: A) has three columns id, name, amount. Amount has some +ve,-ve and zero values. How to write a query to get the amount in such a way that it gives as a result first +ve then -ve then zeros? PFA for the sample table.
Thanks in advance
If you want 3 groups one after the other:
SELECT *
FROM tablename
ORDER BY
(CASE
WHEN amount > 0 then 1
WHEN amount < 0 then 2
ELSE 3
END),
Id;
Are you just looking for order by with a case expression?
select a.*
from a
order by (case when a.amount > 0 then 1
when a.amount < 0 then 2
else 3
end),
a.amount desc;

sql: percentage of a type in a column

I'm trying to get percentage of missed calls for each user, so I used the following sql query:
select distinct a__contact
, count (case when a__type = 'missed'
then 1 else 0 end) / count(*) * 100
as "percentage of missed calls"
from table
group by 1
However, for each user I got 100 which do not seem to be correct output at all. Could someone help me to identify the error in my query? thank you so much!
Here is a simpler way to express the logic you want:
select a__contact,
avg(case when a__type = 'missed' then 100.0 else 0 end) as percentage_missed_calls
from table
group by 1;
Your version is failing because you are using count() in the numerator. You really intend sum(). count() counts the number of non-NULL values and both "1" and "0" are non-NULL.

Get ratio between the length of a table and one of its subsets via SQL

I have a table named A that contains a column named x. What I'm trying to do is to count the number of items that belong to a certain subset of A (more precisely, the ones that satisfy the x > 4 condition) via a single SELECT query, for example:
SELECT COUNT(*)
FROM A
WHERE x > 4;
From thereon, I'd like to calculate the ratio between the size of this particular subset of A and A as a whole, i.e. perform the following division:
size_subset / size_A
My question is - how would I combine all of these pieces into a single SQL SELECT query?
My server is down, not able to get sure of the answer below:
SELECT count(case when x > 4 then x else null end) / COUNT(*) FROM A;
Is a slight better because its just a count, not a sum (nulls ill not be accounted)
but i prefer to do:
select (SELECT count(*) FROM A where x > 4)/(SELECT count(*) FROM A);
As I guess it can do faster
You want conditional aggregation:
SELECT sum(case when x > 4 then 1 else 0 end) / COUNT(*)
FROM A;
There's probably a less clunky way of doing this, but:
SELECT SUM(CASE WHEN x > 4 THEN 1 ELSE 0 END) / COUNT(*) FROM A