Query with multiple SELECT and GROUP BY - mysql

I will count of total area's record where there status will different like 'PENDING','SENT INFO','PTP' with group by and multiple select queries but result not got so plese help me.
My query is:
SELECT AREA,
(SELECT COUNT( * ) FROM prospectmaster WHERE ZONE = 'AHMEDABAD' && STATUS = 'PENDING' GROUP BY AREA) AS PENDING,
(SELECT COUNT( * ) FROM prospectmaster WHERE ZONE = 'AHMEDABAD' && STATUS = 'SENT INFO.' GROUP BY AREA) AS CNT
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD' GROUP BY AREA
I want to this type of result.
AREA PENDING INFO SENT PTP
AHMEDABAD 1 2 1
GANDHINAGAR 1 5 4
KHEDA 3 10 9
I think some problem in query but I doesn't got it.So,Please help me.

SELECT AREA,
SUM(CASE WHEN STATUS = 'PENDING' THEN 1 ELSE 0 END) AS PENDING,
SUM(CASE WHEN STATUS = 'SENT INFO.' THEN 1 ELSE 0 END) AS cnt,
SUM(CASE WHEN STATUS = 'PTP' THEN 1 ELSE 0 END) AS PTP
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD'
GROUP BY AREA;
If STATUS has 'SENT INFO.' record in DB with .

SELECT AREA,
SUM(if(STATUS='PENDING',1,0)) AS PENDING,
SUM(if(STATUS='SENT INFO',1,0)) AS "INFO SENT",
SUM(if(STATUS='PTP',1,0)) AS PTP
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD'
GROUP BY AREA;

Because this is mysql, you can simply do this:
SELECT
AREA,
SUM(STATUS = 'PENDING') AS PENDING,
SUM(STATUS = 'SENT INFO.') AS SENT_INFO,
SUM(STATUS = 'PTP') AS PTP
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD'
GROUP BY AREA
This works because in mysql true is 1 and false is 0, so summing a condition counts how many times its true

Related

Sum on same column with two different conditions mysql

I have a table named Order with schema as
user_id, state amount
11 success 100
11 FAILED 10
11 FAILED 10
11 success 17
state can have two values (Success/Failed).
I want to fetch sum(amount) when state = "SUCCESS" - sum(amount) when state = "FAILED"
means difference total amount when success - total amount when failed.
I can solve this problem in 2 queries.
A = select id, sum(amount) when state = "SUCCESS"
B = select id, sum(amount) when state = "FAILED"
And solution will be A-B.
Is there any way I can achieve this in single sql query?
use case when
select user_id,sum(case when state = 'SUCCESS' then amount else 0 end)-sum(case when state = 'FAILED' then amount else 0 end)
from table group by user_id
Use conditional aggregation:
select id,
sum(case when state = 'SUCCESS' then amount else - amount end) as total
from t
where state in ('SUCCESS', 'FAILED')
group by id;
I assume that you want this sum per id and not overall in the table.
select sum(case when state = "SUCCESS" then amount else o end) -
sum(case when state = "FAILED" then amount else o end)
from tbl
group by userid

Grouping by months and by column with diferent values

I am having problems trying to create a query that allow me to group by months and by a column that has different values.
The following is a small representation of the table and columns I need to query.
Table name is requests and has two columns date and status. Status may have the values pending, attended, absent and canceled.
I want to get a query that looks like this
Right now i am trying a subquery on status for each possible value. It works but is a very slow query. It takes arround 48s for 8000 rows.
SELECT
MONTHNAME(date)
(SELECT count(status) FROM requests WHERE status = "pending"),
(SELECT count(status) FROM requests WHERE status = "attended"),
(SELECT count(status) FROM requests WHERE status = "absent"),
(SELECT count(status) FROM requests WHERE status = "canceled")
FROM request
GROUP BY 1;
Any recommendations on how to get the result efficiently? Thank you very much
You could use case whene on status instead of several subselect
select
MONTHNAME(date)
, sum( case when status = "pending" then 1 else 0 end) pending
, sum( case when status = "attended" then 1 else 0 end) attended
, sum( case when status = "absent" then 1 else 0 end) absent
, sum( case when status = "canceled" then 1 else 0 end) canceled
FROM request
GROUP BY MONTHNAME(date) ;

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.

mysql grouping a status field

I have a table
id, location, status
1, london, 1
2, london, 0
3, boston, 1
4, boston, 1
I'd like my query to generate something like this: -
location, status_1, status_0
london, 1, 1
boston, 2, 0
so far I have: -
select count(id) as freq, location from my_table
group by location order by freq desc;
I'm completely lost as to where to go from here.
That sort of transformation is better done in whatever client is issuing the query, but if you have to do it in the database, then
select location,
sum(status = 1) AS status_1,
sum(status = 0) AS status_0
from my_table
group by location
it's a bit hackish, but the 'status = 1' when status really is 1 will evaluate to a boolean true, which MySQL will politely cast to an integer '1', which then gets summed up. Same goes for when status is 0 and status = 0 evaluates to true.
So you want to count the records for each status per city?
In the query below, I group by location (like your did), and then add a sum for each state. Inside the sum is a case, that either returns 1 if the record matches the desired state, or 0 otherwise. That way, you effectively count the number of records for each state per location.
select
a.location,
sum(case when a.status = 1 then 1 else 0 end) as status_1,
sum(case when a.status = 0 then 1 else 0 end) as status_0
from
YourTable a
group by
a.location
select location,
sum(case when status = 1 then 1 else 0 end) as status_1,
sum(case when status = 0 then 1 else 0 end) as status_0,
from my_table
group by location;