Display the results in 1 row and different columns - mysql

Assume a simple case e.g. a table bug that has a column status that can be open,fixed etc.
If I want to know how many bugs are open I simply do:
select count(*) as open_bugs from bugs where status = 'open';
If I want to know how many bugs are open I simply do:
select count(*) as closed_bugs from bugs where status = 'closed';
If what want to know how many open and how many closed there are in a query that returns the results in 2 columns i.e.
Open | Closed|
60 180
What is the best way to do it? UNION concatenates the results so it is not what I want

This can be done by using a CASE expression with your aggregate function. This will convert the rows into columns:
select
sum(case when status = 'open' then 1 else 0 end) open_bugs,
sum(case when status = 'closed' then 1 else 0 end) closed_bugs
from bugs
This could also be written using your original queries:
select
max(case when status = 'open' then total end) open_bugs,
max(case when status = 'closed' then total end) closed_bugs
from
(
select status, count(*) as total from bugs where status = 'open' group by status
union all
select status, count(*) as total from bugs where status = 'closed' group by status
) d

Besides the CASE variants that aggregate over the whole table, there is another way. To use the queries you have and put them inside another SELECT:
SELECT
( SELECT COUNT(*) FROM bugs WHERE status = 'open') AS open_bugs,
( SELECT COUNT(*) FROM bugs WHERE status = 'closed') AS closed_bugs
FROM dual -- this line is optional
;
It has the advantage that you can wrap counts from different tables or joins in a single query.
There may also be differences in efficiency (worse or better). Test with your tables and indexes.
You can also use GROUP BY to get all the counts in separate rows (like the UNION you mention) and then use another aggregation to pivot the results in one row:
SELECT
MIN(CASE WHEN status = 'open' THEN cnt END) AS open_bugs,
MIN(CASE WHEN status = 'closed' THEN cnt END) AS closed_bugs
FROM
( SELECT status, COUNT(*) AS cnt
FROM bugs
WHERE status IN ('open', 'closed')
GROUP BY status
) AS g

Try this
select count(case when status = 'open' then 1 end) open_bugs,
count(case when status = 'closed' then 1 end) closed_bugs
from bugs

Related

Summing of count result at same level

I'm trying to sum the results of count(id) at the same level, in order to find out the relative portion of the count(id) from the overall count.
The count is grouped by the respective previous number, and I want to stay at the same table and have it all together.
`
select totalattempts, count(totalattempts) allattempts, count(case when success>0 then totalattempts else null end) successfulattempts
from (
select *, case when success> 0 then attemptspresuccess+1 else attemptspresuccess end totalattempts
from (select orderid, count(orderid) attemptspresuccess, count(case when recoveredPaymentId is not null then recoveredPaymentId end ) success from (
select orderid, recoveredPaymentId
from errors
where platform = 'woo'
) alitable
group by orderid) minitable ) finaltable
group by totalattempts
order by totalattempts asc
`
I need to add another column that basically would have, to put it simply, count(totalattempts)/sum(count(totalattempts).
I'm running out of ideas basically.
I can't use windows as this is an app of retool which doesn't support that
Assuming some test data here:
DECLARE #table TABLE (AttemptNumber INT IDENTITY, Success BIT)
INSERT INTO #table (Success) VALUES
(0),(0),(0),(0),(1),(1),(0),(0),(0),(0),(0),(1),(0),(1),(0),(0),
(0),(0),(1),(0),(0),(0),(0),(1),(0),(1),(0),(0),(0),(1),(0),(0)
I sounds like you want to know how many attempts there were, how many were successful and what that is a percentage?
SELECT COUNT(Success) AS TotalCount,
COUNT(CASE WHEN Success = 1 THEN 1 END) AS SuccessCount,
COUNT(CASE WHEN Success = 1.0 THEN 1 END)/(COUNT(Success)+.0) AS SuccessPct
FROM #table
TotalCount SuccessCount SuccessPct
--------------------------------------
32 8 0.2500000000000

SQL count show group by show in column instead of rows

I have a table like this
Now my output would like to be
total_rows | completed | incomplete
------------------------------------
7 2 5
How can I achieve that.
You could use condition aggregation
select count(*) total ,
sum(completed = 1) completed ,
sum(completed = 0) incompleted
from your_table
Try the following.
select
count(*) as total_rows,
sum(case when completed = 1 then 1 else 0 end) as completed,
sum(case when completed = 0 then 1 else 0 end) as incomplete
from myTable
With conditional aggregation:
select
count(*) as total_rows,
sum(completed) completed,
sum(1 - completed) incomplete
from tablename
or:
select
count(*) as total_rows,
sum(completed) completed,
sum(not completed) incomplete
from tablename
I think this will help you
select count(id) as total_rows ,
sum(completed = 1) as completed ,
sum(completed = 0) as incompleted from sales_call_task_jo_iformation;
please try this if you need I will help you

Count specific values in column

I'm trying to count the number of times multiple words appears in a column named sg_event but currently run each one separately. Does anyone know how I can combine this into one query.
select count(*) from metrics
WHERE sg_event = 'open';
select count(*) from metrics
WHERE sg_event = 'delivered';
select count(*) from metrics
WHERE sg_event = 'click';
My desired outcome is as follows,
open_count, delivered_count, click_count
You can use conditional sum for this
select
sum( case when sg_event = 'open' then 1 else 0 end ) as `open_count`,
sum( case when sg_event = 'delivered' then 1 else 0 end ) as `delivered_count`,
sum( case when sg_event = 'click' then 1 else 0 end ) as `click_count`
from metrics
You can use the standard sql feature group by:
SELECT count(*), sg_event
FROM metrics
WHERE sg_event IN ( 'open', 'delivered', 'click')
GROUP BY sg_event;
You should get something like
10 open
15 delivered
76 click
so each line get one sum.
Of course you can sort your results (e.g.: ORDER BY 1, to sort by count column)
This solution is more flexible, cause you can specify a lot more values to inspect (here for sg_event), maybe a join with a table which hold all your interested sg_events.
As shown in the answer by Abhik Chakraborty you can use the caseexpression to conditionally aggregate data, but since MySQL evaluates boolean expressions as 1 or 0 you can reduce the query further to this more compact form:
select
sum(sg_event = 'open') as `open_count`,
sum(sg_event = 'delivered') as `delivered_count`,
sum(sg_event = 'click') as `click_count`
from metrics

SQL Union query error

Im trying to join two count querys
SELECT COUNT(*) AS total FROM clients WHERE addedby = 1
UNION
SELECT COUNT(*) AS converts FROM clients WHERE addedby = 1 AND status = '6'
What this returns is
total
4
0
this is the correct data, what I was expecting was this
total converts
4 0
You don't need a UNION query to do this. SELECT A UNION SELECT B returns the rows of A followed by the rows of B (deduplicated; if you want all rows from both datasets, use UNION ALL).
What you want is something like this:
select
(select count(*) from clients where addedby=1) as total,
(select count(*) from clients where addedby=1 and status='6') as converts
Other way to do this is using a case ... end expression that returns 1 if status='6':
select
count(*) from clients,
sum(case when status='6' then 1 else 0 end) as converts
from clients
No UNION needed, do it in one pass.
SELECT COUNT(*) as total,
SUM(CASE status WHEN '6' THEN 1 ELSE 0 END) as converts
FROM clients;
The simplest way to write this query is as a conditional aggregation:
select count(*) as total, sum(status = '6') as converts
from cleints
where addedby = 1;
MySQL treats booleans as integers with 1 being true and 0 being false. You can just sum of the values to get a count.

Using sum() to mimic count() of rows

I want to count the number of rows where a particular field = 'Q1'.
I usually use count(particular_field), but this does not allow me to count only when that field = 'Q1'.
Does the query SUM(particular_field = 'Q1') work for this matter? Or am I able to do count(particular_field = 'Q1')?
you can either do
select count(*)
from table
where particular_field = 'Q1'
or
select sum(case when particular_field ='Q1' then 1 else 0 end)
from table
You should be able to use a CASE statement with your SUM() (See SQL Fiddle)
SELECT SUM(CASE WHEN particular_field = 'Q1' THEN 1 ELSE 0 END) yourCount
FROM yourTable
Or (See SQL Fiddle) - this will give you a list of the count and each field. If you only want the one value, then use a WHERE clause to filter:
select count(*), particular_field
from yourTable
group by particular_field