Two different counts in the one query - mysql

I have a web page that displays requests received by each user (Firstname) that are separated into 1 of 4 lists based on 4 separate queries which rely on a WHERE statement to check the value of the ‘status’ column (incoming, playlisted, sidelisted, played).
This solution works for the ‘played’ list.
SELECT
t1.FirstName, count(*)
FROM
RequestsTable t1
WHERE t1.status = 'played'
GROUP BY t1.FirstName;
but the WHERE statement doesn’t allow it to work for requests that are in the other 3 lists.
Two counts are required within each of the 4 lists to show
i) the total number of requests made by each user.
ii) the number of requests made by each user that have been ’played’.
All of my attempts to use JOINS and CASE statements have been defeated by the WHERE statement which limits the counts to the records within any 1 of the 4 lists.

Remove the WHERE statement and put the status conditions in the COUNT:
SELECT
t1.FirstName,
count(*) as totalCount,
count(IF(t1.status = 'played',1,null)) as playedCount
FROM
RequestsTable t1
GROUP BY t1.FirstName;

SELECT
t1.FirstName, count(*) cnt ,0 played,0 played2
FROM
RequestsTable t1
GROUP BY t1.FirstName
union
SELECT
t1.FirstName, 0 cnt ,count(*) played,0 played2
FROM
RequestsTable t1
WHERE t1.status = 'played'
GROUP BY t1.FirstName
union
SELECT
t1.FirstName, 0 cnt,0 played ,count(*) played2
FROM
RequestsTable t1
WHERE t1.status = 'played2'
GROUP BY t1.FirstName
Try above query.
Hope this will helps.

Related

why the sql correct and the inner mechanism for run it?

the sql as follows come from mysql document. it is:
SELECT * FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
The document say It finds all rows in table t1 containing a value that occurs twice in a given column , and doesnot explain the sql.
t1 and t is the same table, so the
count(*) in subquery == select count(*) from t
, isn't it?
count(*) in subquery == select count(*) from t
is wrong. because in mysql you can't use it like that. so you have to run it like that to get result of same id having two rows.
if you want to get count of same occurrence,
SELECT id, name, count(*) AS all_count FROM t1 GROUP BY id HAVING all_count > 1 ORDER BY all_count DESC
And also you can get values as your query like this as well,
select * from t1 where id in ( select id from t1 group by id having count(*) > 1 )
The query contains a correlated subquery in WHERE clause:
SELECT COUNT(*) FROM t1 WHERE t1.id = t.id
It is called correlated because it is related to the main query via t.id. So, this subquery counts the number of records having an id value that is equal to the current id value of the record returned by the main query.
Thus, predicate
(SELECT COUNT(*) FROM t1 WHERE t1.id = t.id) = 2
evaluates to true for any row with an id value that occurs twice in the table.
SELECT * FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
This query goes through each record in t1 and then in the subquery looks into t1 again to see if in this case id is found 2 times (and only 2 times). You can do the same for any other column in t1 (or any table for that matter).
When you would like to see all values that are multiple times in the table, change WHERE 2 = by WHERE 1 <. This will also give you the values that are 3 times, 4 times, etc. in the table.
{
SELECT id,count( * )
FROM
MyTable
group by id
having count( * )>1
}
with this code, you can see the rows which repet more than one,
and you can change this query by yourself
How about using GROUP BY and HAVING:
SELECT id, count(1) as Total FROM MyTable AS t1
GROUP BY t1.id
HAVING Total = 2

Unexpected count results

I have the following query which is returning total number of entries in the requests column in the requests table for each given user, rather than the number of requests marked as played for any given user.
SELECT
t1.status, t1.FirstName
t2.CountPlayed
FROM
RequestsTable t1
INNER JOIN
(SELECT t1.FirstName, Count(t1.status ='played') AS CountPlayed
FROM RequestsTable t1
GROUP BY t1.FirstName)
t2 ON t1.FirstName = t2.FirstName
WHERE t1.status = 'played'
Desired results: eg
Fred: 2 (played out of total 6 requests)
Ginger: 1 (played out of total 4 requests)
Lenny: 2 (played out of total 3 requests)
Actual results:
Fred = 6
Ginger = 4
Lenny = 3
That count isn't working the way you think it is. You need to filter using where first.
...
INNER JOIN
(SELECT t1.FirstName, count(*) AS CountPlayed
FROM RequestsTable t1
WHERE t1.status = 'played'
GROUP BY t1.FirstName)
....
Actually you can further simplify the whole thing to just one query:
SELECT
t1.FirstName, count(*)
FROM
RequestsTable t1
WHERE t1.status = 'played'
GROUP BY t1.FirstName;
Try SUM instead of COUNT. COUNT counts 0/false; it only ignores NULL.

COUNT(*) returning number of rows before GROUP BY clause?

I have the follwing query:
SELECT COUNT(*)
FROM mydb.table1 t1
JOIN mydb.table2 t2 ON t1.id = t2.t1_id
WHERE t1.user_id = 44 AND t1.date_deleted IS NULL
GROUP BY t2.system_id, CASE WHEN t2.system_id IS NULL THEN t2.id ELSE 0 END
It returns COUNT(*) = 6, when it should be returning 1 since all six rows for this user have the same t2.system_id (so they should be grouped).
If I change the query to select * instead of COUNT(*), it only returns a single row. If I then remove the GROUP BY clause, six rows are returned.
This makes me think COUNT(*) is returning the row count before the GROUP BY clause is executed, but from what I've read that's not how it's supposed to work.
Is this behavior normal?
Try this:
select count(*) from (
SELECT *
FROM mydb.table1 t1
JOIN mydb.table2 t2 ON t1.id = t2.t1_id
WHERE t1.user_id = 44
AND t1.date_deleted IS NULL
GROUP BY t2.system_id,
CASE WHEN t2.system_id IS NULL THEN t2.id ELSE 0 END
) q1
count gives you the number of (not null) items in each group, so yes, it is definitely working the way it is intended. This means that if you just want the total number of groups, the easiest way is to just wrap it in another query.
It returns the count of items in each group. You have one group with six items in it, so it returns one row containing a column valued 6.

Combining two Count Queries into one

I have theses two queries
SELECT course,
COUNT(*) AS countp
FROM table1
WHERE pickout='Yes'
GROUP BY course
SELECT course,
COUNT(*) AS countw
FROM table1
WHERE pickout='Yes' AND result='Won'
GROUP BY course
what I am trying to achieve is a table with three columns Course, Countp, Countw but I am having trouble combining the two into one query.
Basically I am looking for a list of course with number of picks and then number of wins.
In MySQL the result of conditions evaluate to 1 or 0. You can sum that up
SELECT course,
sum(pickout='Yes') AS countp,
sum(pickout='Yes' AND result='Won') AS countw
FROM table1
GROUP BY course
Try the following SQL:
SELECT
Course,
COUNT(*) AS CountP,
SUM(CASE WHEN result='Won' THEN 1 ELSE 0 END) AS CountW
FROM table1
WHERE pickout = 'Yes'
GROUP BY Course
try this:
select a.course,a.countp ,b.countw from (SELECT course, COUNT(*) AS countp FROM table1 WHERE pickout='Yes' GROUP BY course)a full join
(SELECT course, COUNT(*) AS countw FROM table1 WHERE pickout='Yes' AND result='Won' GROUP BY course)b
a.course=b.course

MySQL merging two queries one with group by

I have two tables, one holds user info (id, name, etc) and another table that holds user tickets and ticket status (ticket_id, user_id, ticket_status, etc).
I want to produce a list of ALL the users for example: ( SELECT * FROM user_table )
And for each user I need a count of their tickets for example:
(SELECT t1.user_id, COUNT(*) FROM user_tickets t1 WHERE t1.ticket_status = 15 GROUP BY t1.ticket_status, t1.user_id )
I can do this query to achieve what I’m looking for but it takes 5sec. to run the query on 50000 tickets, while each query running separately only takes fraction of a second.
SELECT t1.user_id, COUNT(*)
FROM user_tickets t1
LEFT JOIN user_table t2 ON t1.user_id = t2.id
WHERE t2.group_id = 20 AND t1.status_id = 15
GROUP BY t1.status_id, user_id
Any idea how to write the query to get same performance as each separately?
An indexing where clause fixed the problem.