How to combine two count queries to their ratio? - mysql

I have two queries:
select count(*) from my_table where status="accepted"
and
select count(*) from my_table where status="rejected"
I was to find the ratio of accepted/reject so I Was wondering if it's possible to combine the two queries so I don't have to execute two queries

Putting this answer since none offered so far is correct
select count(case when status = "accepted" then 1 end) /
count(case when status = "rejected" then 1 end) as Ratio
from my_table
where status in ("accepted","rejected")
If you also need the individual counts
select count(case when status = "accepted" then 1 end) Accepted,
count(case when status = "rejected" then 1 end) Rejected,
count(case when status = "accepted" then 1 end) /
count(case when status = "rejected" then 1 end) as Ratio
from my_table
where status in ("accepted","rejected")
Note: MySQL does not have a divide by zero problem. It returns NULL when Rejected is 0.

select accepted_count, rejected_count, accepted_count/rejected_count ratio
from (
select sum(CASE WHEN status="accepted" THEN 1 ELSE 0 END) accepted_count,
sum(CASE WHEN status="rejected" THEN 1 ELSE 0 END) rejected_count
from my_table
) A

I think this will work:
SELECT (Select count(*) from my_table where status="accepted") / (select count(*) from my_table where status="rejected") AS ratio

select status, count(*) from my_table
where status in ("rejected", "accepted")
group by status;

select sum(case when status='accepted' then 1 else 0 end) as AcceptedCount,
sum(case when status='rejected' then 1 else 0 end) as RejectedCount
from my_table

Related

SQL - Calculate percentage of multiple counts

I wrote a query to count and group all items in db by it's status.
Now, I need to calculate percentage of every given result.
SELECT
COUNT(CASE WHEN status='Pending' THEN 1 ELSE NULL END) as 'Pennding Requests',
COUNT(CASE WHEN status='Accepted' THEN 1 ELSE NULL END) as 'Accepted Requests',
COUNT(CASE WHEN status='Denied' THEN 1 ELSE NULL END) as 'Denied Requests'
FROM meeting_request;
which gave me:
enter image description here
I tried something like:
100.0 * (id / Pennding Requests) AS PERCENTAGE
Can some one suggest how to calculate percentage all of three status.
You can use AVG():
SELECT AVG( status = 'Pending' ) as pending_requests,
AVG( status = 'Accepted' ) as Accepted_Requests,
AVG( status = 'Denied' ) as Denied_Requests
FROM meeting_request;
Because MySQL interprets booleans as numbers with 1 for true and 0 for false, you can use the handy shortcut. The more formal SQL code is:
SELECT AVG(CASE WHEN status = 'Pending' THEN 1.0 ELSE 0 END)
Have you tried doing it like this?
SELECT
COUNT(CASE WHEN status='Pending' THEN 1 ELSE NULL END) / SUM(1) * 100.0 as 'Pennding Requests Percent',
COUNT(CASE WHEN status='Accepted' THEN 1 ELSE NULL END) / SUM(1) * 100.0 as 'Accepted Requests Percent',
COUNT(CASE WHEN status='Denied' THEN 1 ELSE NULL END) / SUM(1) * 100.0 as 'Denied Requests Percent'
FROM meeting_request;

Multiple Count with Multiple column

I am new in sql. I want to count something like:
Select count(*) from table where col1= x and col2=x and Col3=x.
I need to count the same value in all different column.
Any help will be appreciated.
You can use conditional aggregation :
Select sum(case when col1='x' then 1 else 0 end) as count_col1,
sum(case when col2='x' then 1 else 0 end) as count_col2,
sum(case when col3='x' then 1 else 0 end) as count_col3
from tab;
If you want to have sum of these count values, consider the above query as an inner and use the following :
Select q.*,
q.count_col1 + q.count_col2 + q.count_col3 whole_sum
from
(
Select sum(case when col1='x' then 1 else 0 end) as count_col1,
sum(case when col2='x' then 1 else 0 end) as count_col2,
sum(case when col3='x' then 1 else 0 end) as count_col3
from tab
) q
Rextester Demo

Count different values in a column, while doing total and group by different column values

We have a table with data from different nodes and one of the column will have status report as "compliant or non-compliant", sample data as below
I want to filter the table in such a way that if any of the checks on a node shows non compliant, it should be flagged as non-compliant and rest as compliant. Using below query i am able to do it
SELECT COUNT(*) AS total_nodes,
SUM(fully_compliant = 0) AS Non_compliant_nodes,
SUM(fully_compliant = 1) AS compliant_nodes
FROM (
SELECT Node, CASE WHEN SUM(Status = 'Compliant') = COUNT(*) THEN 1 ELSE 0 END AS fully_compliant
FROM your_table GROUP BY Node
)
Now, i want to group and split the result by dept as below, how can i achieve this
I think you're looking for this:
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
sum(case when 'Non-Compliant' then 1 else 0 end) as non_compliant_chk
from your_table
group by dept,
node
) v
group by dept;
With few modifications to what Brian suggested, I am able to get the desired result
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
COUNT(CASE WHEN Compliance-Status = 'Non-Compliant' THEN 1 END) 'non_compliant_chk'
from table WHERE DOR >= DATE(NOW()) - INTERVAL 7 DAY
group by Dept,
Node
) v
group by Dept;

Get both results with one query

I want to get results for likes by a specific user-id and all likes and dislikes of a specific page id.
My structure looks like this:
`pages`: (id, title)
`pages_likes`: (id, page_id, uid, status)
If the status is -1 it's a dislike of a specific page, if it's 1 it's a like.
So, to get all likes this is my query:
SELECT COUNT(id) FROM pages_likes WHERE status = '1'
But now I also want to get if user-id 3 for example likes this page with
SELECT COUNT(id) FROM pages_likes WHERE status = '1' AND uid='3'
How can I achieve both in one query? I guess there has to be changed something right after the SELECT statement?
If you want to do this in a single query, use conditional aggregation:
SELECT SUM(CASE WHEN uid = '3' THEN 1 ELSE 0 END) AS threeLikes,
SUM(CASE WHEN uid <> '3' THEN 1 ELSE 0 END) AS otherLikes
FROM pages_likes
WHERE status = '1'
Another option would be to use a UNION, cf. the answer given by #bernie
Update:
If you want page likes and dislikes in the same query, you can try:
SELECT SUM(CASE WHEN uid = '3' AND status = '1' THEN 1 ELSE 0 END) AS threeLikes,
SUM(CASE WHEN uid <> '3' AND status = '1' THEN 1 ELSE 0 END) AS otherLikes
SUM(CASE WHEN uid = '3' AND status = '0' THEN 1 ELSE 0 END) AS threeDislikes,
SUM(CASE WHEN uid <> '3' AND status = '0' THEN 1 ELSE 0 END) AS otherDisikes
FROM pages_likes
I think this would work:
SELECT '' user, COUNT(id) likes
FROM pages_likes
WHERE status = '1'
GROUP BY 1
UNION ALL
SELECT uid user, COUNT(id) likes
FROM pages_likes
WHERE status = '1' AND uid='3'
GROUP BY 1
I would do it this way:
SELECT COUNT(*) AS total_likes, SUM(uid=3) AS uid3_likes
FROM pages_likes
WHERE status=1 AND page_id=1234
Re your comment:
Here's an example of showing total likes, and total dislikes. It's similar to the answer from #TimBiegeleisen.
SELECT SUM(status=1) AS total_likes,
SUM(CASE WHEN uid=3 AND status=1 THEN 1 END) AS uid3_likes
SUM(CASE WHEN uid=3 AND status=-1 THEN 1 END) AS uid3_dislikes
FROM pages_likes
WHERE page_id=1234

Sum record between two dates for different users in mysql query Issue

I have two tables lead and lead_details. There is a field status. If status=1 is open, status=2 is close and status=3 is not specified.
I want to find sum of all Open,close and not specified for each user/agent.
Here is what I tried but it give me wrong data
select agent_id,
type,
status,
created_date,
category_id,
sum(case when status = 2 then val else 0 end) as closed1,
sum(case when status = 1 then val else 0 end) as opened1,
sum(case when status = 3 then val else 0 end) as notspecefied1
from ( select l.agent_id,
l.type,
ld.category_id,
l.status,
l.created_date,
count(*) as val
from crm_leads l,
crm_leads_details ld
where l.id=ld.lead_id AND
status in (2, 1, 3)
GROUP BY status, agent_id
) t
WHERE created_date BETWEEN '2013-8-2' AND '2013-9-2'
GROUP BY agent_id
You need to put the WHERE created_date clause in the subquery.
select agent_id,type,status,created_date,category_id,
sum(case when status = 2 then val else 0 end) as closed1,
sum(case when status = 1 then val else 0 end) as opened1,
sum(case when status = 3 then val else 0 end) as notspecefied1
from ( select l.agent_id,l.type,ld.category_id,l.status,l.created_date,
count(*) as val from crm_leads l JOIN crm_leads_details ld
ON l.id=ld.lead_id
WHERE created_date BETWEEN '2013-8-2' AND '2013-9-2' AND status in (2, 1, 3)
GROUP BY status, agent_id ) t
GROUP BY agent_id
Note that the created_date in the result will just be a randomly selected date in the period for each agent.