I wrote a query. The query and its output can be found below.
Well, I need a query that takes this query as subquery and it will produce output like below. I prepared some queries but they didn't work, generaly they brought null for each month value. There might be another better apporach for this kind of problems. I have just tried like that.
Ideally, you will have to use something like PIVOT() in SQL. Unfortunately, it is not available in MySQL. So this will work:
SELECT customer,
MAX(CASE WHEN month='January' THEN total_count ELSE 0 END) AS Jan,
MAX(CASE WHEN month='February' THEN total_count ELSE 0 END) AS Feb,
MAX(CASE WHEN month='March' THEN total_count ELSE 0 END) AS Mar,
MAX(CASE WHEN month='April' THEN total_count ELSE 0 END) AS Apr,
MAX(CASE WHEN month='May' THEN total_count ELSE 0 END) AS May,
MAX(CASE WHEN month='June' THEN total_count ELSE 0 END) AS Jun,
MAX(CASE WHEN month='July' THEN total_count ELSE 0 END) AS Jul,
MAX(CASE WHEN month='August' THEN total_count ELSE 0 END) AS Aug,
MAX(CASE WHEN month='September' THEN total_count ELSE 0 END) AS Sep,
MAX(CASE WHEN month='October' THEN total_count ELSE 0 END) AS Oct,
MAX(CASE WHEN month='November' THEN total_count ELSE 0 END) AS Nov,
MAX(CASE WHEN month='December' THEN total_count ELSE 0 END) AS Decem
FROM t
GROUP BY customer
Note:
t must be replaced with your entire query as sub-query
Taking MAX, MIN or SUM will give us the same result as it is already grouped at month and customer level
If you wanna use Dec for last column name, use it as "Dec" otherwise MySQL will throw an error (due to keyword is used)
Look at the Demo in db<>fiddle
Related
I have a table of phone call activity for a client. In the table, I have one column for the length of the call (in seconds), and another column for "first time call" (true / false). I was hoping to find a way to get the average call length of first time calls separated from the average time of non first time calls? Is this doable in a singe mySQL query?
SELECT location,
count(*) AS total,
sum(case when firstCall = 'true' then 1 else 0 end) AS firstCall,
sum(case when answered = 'Yes' then 1 else 0 end) AS answered,
sum(case when tags like '%Lead%' then 1 else 0 end) as lead,
sum(case when tags like '%arbage%' then 1 else 0 end) as garbage,
avg(case when duration........firstTime = True???)
FROM staging
GROUP BY location
SELECT location,
count(*) AS total,
sum(case when firstCall = 'true' then 1 else 0 end) AS firstCall,
sum(case when answered = 'Yes' then 1 else 0 end) AS answered,
sum(case when tags like '%Lead%' then 1 else 0 end) as lead,
sum(case when tags like '%arbage%' then 1 else 0 end) as garbage,
sum(case when firstCall='true' then duration else 0 end)/sum(case when firstCall = 'true' then 1 else 0 end) as first_call_true_average,
sum(case when firstCall='false' then duration else 0 end)/sum(case when firstCall = 'false' then 1 else 0 end) as first_call_false_average
FROM staging
GROUP BY location
I would phrase this as:
select
location,
count(*) as total,
sum(firstcall = 'true' ) as cnt_firstcall,
sum(answered = 'Yes' ) as cnt_answered,
sum(tags like '%Lead%' ) as cnt_lead,
sum(tags like '%arbage%') as cnt_garbage,
avg(case when firstcall = 'true' then duration end) as avg_first_call,_duration
avg(case when firstcall = 'false' then duration end) as avg_non_first_call_duration
from staging
group by location
Rationale:
MySQL interpret true/false conditions as 1/0 values in numeric context, which greatly shortens the conditional sum()s
avg() ignores null values, so a simple case expression is sufficient to compute the conditional averages
I have 70 different types of accounts. And I am fetching the data as per the account type.
The query like this,
$mainData = "SELECT
count(*) AS totalRows,
sum(pay) as totalPay
sum(case when account_type = 1 then 1 else 0 end) AS account_1_Total,
sum(case when account_type = 1 then pay else 0 end) AS account_1_Pay,
sum(case when account_type = 2 then 1 else 0 end) AS account_2_Total,
sum(case when account_type = 2 then pay else 0 end) AS account_2_Pay,
{all_account_types_here}
FROM account_table";
In the end, those sum() are about more than 140.
So the question is, how many sum() is recommended in a single query?
Thanks!
EDITED:
The GROUP BY is the solution of it.
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
I want to display a table with SQL query like this:
I have run my query:
select
tb_r_orderdata.finishtime as date ,
count(*)sum all,
sum(when status = 'SUCCESS' and issync = '1' then 1 else 0 end) sumpaid,
sum(when status = 'SUCCESS' and issync in ('3', '4') then 1 else 0 end) sumfail,
sum(when status = 'CLOSED' then 1 else 0 end) sumclose,
sum(when status = 'Null' then 1 else 0 end) sumunflag
from
tb_r_orderdata;
But when I execute it, the result is different than what I expected. The result is like this:
Thank you for any help
You are missing the GROUP BY and the CASE:
select tb_r_orderdata.finishtime as date ,
COUNT(*) as sumall,
SUM(CASE WHEN status='SUCCESS' AND issync='1' then 1 ELSE 0 END) as sumpaid,
SUM(CASE WHEN status='SUCCESS' AND issync in ('3','4') then 1 ELSE 0 END) as sumfail,
SUM(CASE WHEN status='CLOSED' then 1 ELSE 0 END) as sumclose,
SUM(CASE WHEN status is null then 1 ELSE 0 END) as sumunflag
from tb_r_orderdata
group by tb_r_orderdata.finishtime ;
MySQL treats booleans as integers in a numeric context, with "1" for true and "0" for false. You can simplify your query to:
select o.finishtime as date ,
COUNT(*) as sumall,
SUM(status = 'SUCCESS' AND issync = '1') as sumpaid,
SUM(status = 'SUCCESS' AND issync in ('3', '4')) as sumfail,
SUM(status = 'CLOSED') as sumclose,
SUM(status is null) as sumunflag
from tb_r_orderdata o
where tb_r_orderdata.finishtime is not NULL
group by o.finishtime ;
This also removes NULL finish times.
Explanation in comment for Gordon Linoff
i have try your answer but there is record NULL in the top of table, i dont know why, can you explain it
with little bit change from Gordon Linoff answer
select tb_r_orderdata.finishtime as date ,
SUM(CASE WHEN status='SUCCESS' AND issync='1' then 1 ELSE 0 END) as sumpaid,
SUM(CASE WHEN status='SUCCESS' AND issync in ('3','4') then 1 ELSE 0 END) as sumfail,
SUM(CASE WHEN status='CLOSED' then 1 ELSE 0 END) as sumclose,
SUM(CASE WHEN status='NULL' then 1 ELSE 0 END) as sumunflag
from tb_r_orderdata
group by tb_r_orderdata.finishtime
I am trying to total up the columns in a Count Case query. I have the following query
SELECT distinct type,
Year(`date_ready`) as Year,
Count(case when month(`date_ready`)=1 then `type` end) As Jan_Attr,
Count(case when month(`date_ready`)=2 then `type ` end) As Feb_Attr,
Count(case when month(`date_ready`)=3 then `type ` end) As Mar_Attr,
Count(case when month(`date_ready`)=4 then `type ` end) As Apr_Attr,
Count(case when month(`date_ready`)=5 then `type ` end) As May_Attr,
Count(case when month(`date_ready`)=6 then `type ` end) As Jun_Attr,
Count(case when month(`date_ready`)=7 then `type ` end) As Jul_Attr,
Count(case when month(`date_ready`)=8 then `type ` end) As Aug_Attr,
Count(case when month(`date_ready`)=9 then `type ` end) As Sep_Attr,
Count(case when month(`date_ready`)=10 then `type ` end) As Oct_Attr,
Count(case when month(`date_ready`)=11 then `type ` end) As Nov_Attr,
Count(case when month(`date_ready`)=12 then `type ` end) As Dec_Attr
FROM newsuit
GROUP BY Year(`date_ready`), type
What I would like is to get a row called Total, then the total for Jan, total for Feb etc. I presume I need a Sum somewhere, but whatever I try seems to give me the total in the wrong column. I'm guessing that maybe I need to wrap the whole query in another, but I can't seem to get the syntax right.
If I put Sum(type) as Total in the select, I just get one cell with the total in. All the other things I have tried give me errors.
Cheers....
Additional discovery. I've found that the following addition before the From clause adds totals to each row. This is useful, however I still want to find the totals for the columns :)
sum(case when month(`date_ready`) <13 then 1 else 0 end) as Total
Further additional discovery....
This gives me the column totals, just need to combine the two queries.
Select Sum(PQ.Jan_Attr) As JanTot, Sum(PQ.Feb_Attr) As FebTot,Sum(PQ.Mar_Attr) As MarTot,Sum(PQ.Apr_Attr) As AprTot,Sum(PQ.May_Attr) As MayTot,Sum(PQ.Jun_Attr) As JunTot,
Sum(PQ.Jul_Attr) As JulTot,Sum(PQ.Aug_Attr) As AugTot,Sum(PQ.Sep_Attr) As SepTot,Sum(PQ.Oct_Attr) As OctTot,Sum(PQ.Nov_Attr) As NovTot ,Sum(PQ.Dec_Attr) As DecTot
From
(SELECT distinct type,
Year(`date_ready`) as Year,
Count(case when month(`date_ready`)=1 then `type` end) As Jan_Attr,
Count(case when month(`date_ready`)=2 then `type` end) As Feb_Attr,
Count(case when month(`date_ready`)=3 then `type` end) As Mar_Attr,
Count(case when month(`date_ready`)=4 then `type` end) As Apr_Attr,
Count(case when month(`date_ready`)=5 then `type` end) As May_Attr,
Count(case when month(`date_ready`)=6 then `type` end) As Jun_Attr,
Count(case when month(`date_ready`)=7 then `type` end) As Jul_Attr,
Count(case when month(`date_ready`)=8 then `type` end) As Aug_Attr,
Count(case when month(`date_ready`)=9 then `type` end) As Sep_Attr,
Count(case when month(`date_ready`)=10 then `type` end) As Oct_Attr,
Count(case when month(`date_ready`)=11 then `type` end) As Nov_Attr,
Count(case when month(`date_ready`)=12 then `type` end) As Dec_Attr,
sum(case when month(`date_ready`) <13 then 1 else 0 end) as Total
FROM newsuit
WHERE Year(`date_ready`) = '2013'
GROUP BY Year(`date_ready`), type) as PQ
UPDATE 13/02/2014 - I've solved this one now, sort of. I couldn't get what I wanted in a single query, so in the event, I've run the two queries above and just used PHP to display it all as one table. Seemed to be the simplest way in the end.
If anyone would like to know how I did this, I'll happily post / send the code I used to create the tables and format it for displaying data from multiple queries.
I was just asking a similar question, why not try this:
sum(case when year(`date_ready`) = '2013' then 1 else 0 end) as Total
How about
SELECT
suit_type,
Year(`date_ready`) as Year,
SUM(IF(month(`date_ready`) = 1,`type`,0)) AS Jan_Attr,
...
FROM newsuit
GROUP BY Year(`date_ready`), suit_type