count multiple columns in one query - mysql

Guys i have four queries:
Query #1:
select
satisfaction_score,count(satisfaction_score) as Satisfaction_count
from j_survey_response
where satisfaction_score != 0
group by satisfaction_score
The output will be
satisfaction_score Satisfaction_count
1 5
2 8
3 97
4 329
5 859
Query #2:
select
response_score,count(response_score) as response_count
from j_survey_response
where response_score != 0
group by response_score
OUTPUT
response_score response_count
1 28
2 8
3 42
4 250
5 980
Query #3:
select
responder_score,count(responder_score) as responder_count
from j_survey_response
where responder_score != 0
group by responder_score
OUTPUT
responder_score responder_count
1 24
2 3
3 30
4 236
5 987
Query #4:
select
service_score,count(service_score) as service_count
from j_survey_response
where service_score != 0
group by service_score
OUTPUT
service_score service_count
1 22
2 2
3 34
4 270
5 966
But I need the output as below
score satisfaction_count response_count responder_count service_count
1 5 28 24 22
2 8 8 3 2
3 97 42 30 34
4 329 250 236 270
5 859 980 986 966

You can UNION ALL the separate queries and apply conditional aggregation on the resulting set:
select score,
max(case when type = 'satisfaction' then count end) as satisfaction_count,
max(case when type = 'response' then count end) as response_count,
max(case when type = 'responder' then count end) as responder_count,
max(case when type = 'service' then count end) as service_count
from (
select satisfaction_score as score,
count(satisfaction_score) as count,
'satisfaction' as type
from j_survey_response
where satisfaction_score != 0
group by satisfaction_score
union all
select response_score,
count(response_score) as count, 'response' as type
from j_survey_response
where response_score != 0
group by response_score
union all
select responder_score,
count(responder_score) as count, 'responder' as type
from j_survey_response
where responder_score != 0
group by responder_score
union all
select service_score,
count(service_score) as count, 'service' as type
from j_survey_response
where service_score != 0
group by service_score) as t
group by score

Move them in subqueries and join them by score columns. Like this
select
q1.satisfaction_score as score,
q1.satisfaction_count,
q2.response_count,
q3.responder_count ,
q4.service_count,
from (query 1) q1
join (query 2) q2 on q1.satisfaction_score=q2.response_score
join (query 3) q3 on q1.satisfaction_score=q3.responder_score
join (query 4) q4 on q1.satisfaction_score=q3.service_score

You Try this Sql Query
select service_score , count(satisfaction_score) as Satisfaction_count,
count(response_score) as response_count,count(responder_score) as `responder_count,
count(service_score) as service_count from j_survey_response
where service_score != 0 and responder_score != 0 and response_score != 0 and satisfaction_score != 0`
if you use group by
select service_score , count(satisfaction_score) as Satisfaction_count,
count(response_score) as response_count,count(responder_score) as `responder_count,
count(service_score) as service_count from j_survey_response
where service_score != 0 and responder_score != 0 and response_score != 0 and satisfaction_score != 0`
group by satisfaction_score,response_score,responder_score,service_score

Related

The minimum value from each category

I want to get out the minimum price for categories 1, 2 and 3
I've used
LEAST(MIN(price_reduced),MIN(price))
IFNULL(MIN(price_reduced),MIN(price)) ... WHERE price <> 0 and price_reduced <> 0
Database
id
category
price
price_reduced
1
1
200
100
2
1
300
0
3
1
500
0
4
2
200
150
5
2
125
0
6
3
300
0
7
3
200
90
Output
1 - 100
2 - 125
3 - 90
Thank you
This query will work on all MySQL V4+ :
SELECT Category,
MIN(IF((price_reduced > 0) AND (price_reduced < price), price_reduced, price)) AS P
FROM your_table GROUP BY Category;
Maybe with cte:
WITH cte AS (SELECT category,
MIN(price) AS mp,
MIN(CASE WHEN price_reduced <= 0 THEN 9999 ELSE price_reduced END) pr
FROM mytable
GROUP BY category)
SELECT category, LEAST(mp, pr) AS min_val
FROM cte;
Or without cte but with derived table:
SELECT category, LEAST(mp, pr) AS min_val
FROM (SELECT category,
MIN(price) AS mp,
MIN(CASE WHEN price_reduced <= 0 THEN 9999 ELSE price_reduced END) pr
FROM mytable
GROUP BY category) a;
Or just a single query:
SELECT category,
LEAST(MIN(price),
MIN(CASE WHEN price_reduced <= 0 THEN 9999 ELSE price_reduced END)) AS min_val
FROM mytable
GROUP BY category;
All return the same results.
Demo fiddle

mysql - why condition where is not work?

SELECT
t1.user_id,
count(*) total,
sum(case when t1.var1 = 'yes' then 1 else 0 end) as type1,
sum(case when t1.var1 = 'no' then 1 else 0 end) as type2
FROM table as t1
WHERE type1 > 0
GROUP by t1.user_id
ORDER by type1 DESC
LIMIT 100
In result i get rows:
user_id total type1 type2
1 100 80 20
4 120 70 50
6 90 0 90
Tell me please why condition WHERE type1 > 0 not work and how select rows with this condition ?
The WHERE only works on the original value and not on a variable you just made by summing the other values up, you can use HAVING for this:
SELECT
t1.user_id,
count(*) total,
sum(case when t1.var1 = 'yes' then 1 else 0 end) as type1,
sum(case when t1.var1 = 'no' then 1 else 0 end) as type2
FROM table as t1
GROUP by t1.user_id
HAVING type1 > 0
ORDER by type1 DESC
LIMIT 100
See here for another example of using HAVING: http://www.w3schools.com/sql/sql_having.asp

Why MySQL full outer join returns nulls?

Why MySQL full outer join returns nulls?
Hi
I have the following data:
s_id,date,p_id,amount_sold
1, '2015-10-01', 1, 10
2, '2015-10-01', 2, 12
7, '2015-10-01', 1, 11
3, '2015-10-02', 1, 11
4, '2015-10-02', 2, 10
5, '2015-10-15', 1, 22
6, '2015-10-16', 2, 20
8, '2015-10-22', 3, 444
and i want my query to output something like this: (A = sum of amount_sold for p_id=1 for that date,B = sum of amount_sold for p_id=2 for that date)
date,A,B,Difference
'2015-10-01',21,12,9
'2015-10-02',11,10,1
'2015-10-15',22,0,22
'2015-10-01',0,20,-20
I tried with this query, but the order its returning is having NULLS and the output is wrong:
SELECT A.p_id,A.date,sum(A.amount_sold) A,B.Bs, (sum(A.amount_sold) - B.Bs) as difference FROM sales as A
LEFT JOIN (
SELECT SUM( amount_sold ) Bs,p_id,s_id, DATE
FROM sales
WHERE p_id =2
group by date
) as B ON A.s_id = B.s_id
where A.p_id=1 or B.p_id=2
group by A.date, A.p_id
UNION
SELECT A.p_id,A.date,sum(A.amount_sold) A,B.Bs, (sum(A.amount_sold) - B.Bs) as difference FROM sales as A
RIGHT JOIN (
SELECT SUM( amount_sold ) Bs,p_id,s_id, DATE
FROM sales
WHERE p_id =2
group by date
) as B ON A.s_id = B.s_id
where B.p_id=2
group by A.date, A.p_id
It returned:
p_id date A Bs difference
1 2015-10-01 21 NULL NULL
2 2015-10-01 12 12 0
1 2015-10-02 11 NULL NULL
2 2015-10-02 10 10 0
1 2015-10-15 22 NULL NULL
2 2015-10-16 20 20 0
What am i doing wrong here? and what is the correct way of doing it? any help would be appreciated.
A full join isn't needed. You can use conditional aggregation instead:
select
date,
sum(case when p_id = 1 then amount_sold else 0 end) a,
sum(case when p_id = 2 then amount_sold else 0 end) b,
sum(case when p_id = 1 then amount_sold else 0 end)
- sum(case when p_id = 2 then amount_sold else 0 end) difference
from sales
where p_id in (1,2)
group by date

MySQL calculate from same value

i have this query:
SELECT `item_code`,
`q_rr`,
`q_srs`,
#running_bal := #running_bal + (`q_rr` - `q_srs`) as `Balance`
FROM records, (SELECT #running_bal := 0) tempName
order by
records.item_code,
records.date
which results is:
item_code | q_rr | q_srs | balance
--------------------------------------------
0F02206A 2 0 2
BR00113D 3 0 5
BR00114D 10 0 15
BR00114D 0 1 14
BR00114D 0 1 13
BR00115D 20 0 33
BR00115D 0 1 32
BR00115D 0 1 31
need help to make the result to calculate the balance, if q_rr(+) and q_srs(-) and calculate per item_code.
item_code | q_rr | q_srs | balance
--------------------------------------------
0F02206A 2 0 2
BR00113D 3 0 3
BR00114D 10 0 10
BR00114D 0 1 9
BR00114D 0 1 8
BR00115D 20 0 20
BR00115D 0 1 19
BR00115D 0 1 18
I added #code variable to track item_code changes:
SELECT
r.item_code,
r.q_rr,
r.q_srs,
#running_bal := IF(#code = r.item_code, #running_bal, 0) + (r.q_rr - r.q_srs) as Balance,
#code := r.item_code AS dummy
FROM
records r
CROSS JOIN
(SELECT #running_bal := 0, #code := '') tempName
ORDER BY
r.item_code,
r.date
SQL Fiddle: http://sqlfiddle.com/#!2/04ef2b/11
You can eliminate dummy column by putting this as subquery in another select:
SELECT item_code, q_rr, q_srs, Balance
FROM (
-- there put first query
) r
SQL Fiddle: http://sqlfiddle.com/#!2/04ef2b/12
Try this:
SELECT `item_code`,
`id`,
`type`,
#running_bal := case when type = 0 then id
else #running_bal + (`id` - `type`) end as `Balance`
FROM supportContacts, (SELECT #running_bal := 0) tempName
order by
supportContacts.item_code
SQL FIDDLE

Count with Aggreate function in SQL

Hi my actual code is below:
Select M.TicketID,M.CreatedMoment, Max(L.StatusChangeMoment)AS StatusChangeTime,
Elapsed_time_in_Hours_Minutes = CONVERT(NUMERIC(18,2),DATEDIFF(minute, M.createdmoment, MAX(L.statuschangemoment))/60+(DATEDIFF(minute, M.createdmoment, MAX(L.statuschangemoment)) % 60/100.0))
From XX_MASTER_TICKETS AS M Left Join XX_DETAIL_TICKET_STATUS_LOG AS L
On M.RowID = L.TicketRowID
Where M.CreatedMoment between '08-23-2014' And '08-26-2014'
Group by M.TicketID,M.CreatedMoment
Order by M.TicketID asc
And the Partial Results is this:
TicketID CreatedMoment StatusChangeTime Elapsed_time_in_Hours_Minutes
201408231 8/23/14 8:05 AM 8/25/14 11:47 AM 51.42
2014082310 8/23/14 8:19 AM 8/23/14 12:43 PM 4.24
20140823100 8/23/14 8:38 AM 8/24/14 11:15 AM 26.37
20140823101 8/23/14 8:38 AM 8/23/14 11:58 AM 3.2
20140823102 8/23/14 8:38 AM 8/24/14 10:33 AM 25.55
Basically the statuschangetime came from aggregate function, and the last column is the difference of the 2nd and 3rd column.
I want to modify the query so the results will look like this:
Date below24Hrs above24hours
2014-8-23 2 3
My problem is i'm getting error when running this code:
Select
[below24hrs] = COUNT (Case WHEN (CONVERT(NUMERIC(18,2),DATEDIFF(minute, TM.createdmoment, MAX(LG.statuschangemoment))/60+(DATEDIFF(minute, TM.createdmoment, MAX(LG.statuschangemoment)) % 60/100.0))) < 24 THEN 1 END)
From XX_MASTER_TICKETS AS M Left Join XX_DETAIL_TICKET_STATUS_LOG AS L
On M.RowID = L.TicketRowID
Where M.CreatedMoment between '08-23-2014' And '08-26-2014'
Group by M.TicketID,M.CreatedMoment
Order by M.TicketID asc
It says cannot count with the MAX aggregrate function inside the query.
You need to use subquery and sum them.
select cast(sqry.CreatedMoment as date) as CreatedMoment
, sum(case when Elapsed_time_in_Hours_Minutes < 24 then 1 else 0 end) as below24Hrs
, sum(case when Elapsed_time_in_Hours_Minutes > 24 then 1 else 0 end) as above24Hrs
, sum(case when Elapsed_time_in_Hours_Minutes = 24 then 1 else 0 end) as At24Hrs
from
(
Select M.TicketID,M.CreatedMoment, Max(L.StatusChangeMoment)AS StatusChangeTime,
Elapsed_time_in_Hours_Minutes = CONVERT(NUMERIC(18,2),DATEDIFF(minute, M.createdmoment, MAX(L.statuschangemoment))/60+(DATEDIFF(minute, M.createdmoment, MAX(L.statuschangemoment)) % 60/100.0))
From XX_MASTER_TICKETS AS M Left Join XX_DETAIL_TICKET_STATUS_LOG AS L
On M.RowID = L.TicketRowID
Where M.CreatedMoment between '08-23-2014' And '08-26-2014'
Group by M.TicketID,M.CreatedMoment
Order by M.TicketID asc
) sqry
group by cast(CreatedMoment as date)