mysql: query combining info from 2 tables - mysql

Suppose the following configuration:
Table 1 "generic" with fields: id & name
Table 2 "info" with fields: userId (and some others)
When there is info to be stored, there will be records added to the info table. I can easily get a nice overview of the number of records for each user like:
mysql> SELECT userId ,COUNT(*) as nbr_entries FROM info GROUP BY userId ORDER BY nbr_entries DESC;
+-----------+-------------+
| userId | nbr_entries |
+-----------+-------------+
| 3987 | 2254 |
| 11220 | 1922 |
...
Now, my question: I would like to have each userId to be looked up in Table 1 (generic), so that my query result would like like:
+-----------+-----------+-------------+
| name | userId | nbr_entries |
+-----------+-----------+-------------+
| Peter | 3987 | 2254 |
| Walter | 11220 | 1922 |
...
Any idea how to achieve this?
Thanks in advance.

You could use JOIN
SELECT b.name,userid,COUNT(*) as nbr_entries FROM info a
inner join generic b on a.userid=b.id
GROUP BY b.name,userId
ORDER BY nbr_entries DESC;

You can use subquery & JOIN
SELECT t1.name, t2.userId , t2.nbr_entries
FROM generic t1
JOIN
(SELECT userId ,COUNT(*) as nbr_entries FROM info GROUP BY userId) t2
ON t1.userId = t2.userId ORDER BY t2.nbr_entries DESC;

Use a LEFT JOIN:
SELECT g.name, g.id as userId, COUNT(i.userId) as nbr_entries
FROM generic g
LEFT JOIN info i ON i.userId = g.id
GROUP BY g.id
ORDER BY nbr_entries DESC
This way you will also include users who has no info entries (yet) and get 0 as nbr_entries.

Related

mysql count the number of matches based on a column

This is my example dataset I have groups with students assigned to them as shown below
uid | groupid | studentid
49 | PZV7cUZCnLwNkSS | wTsBSkkg4Weo8R3
50 | PZV7cUZCnLwNkSS | aIuDhxfChg3enCf
97 | CwvkffFcBCRbzdw | hEwLxJmnJmZFAic
99 | CwvkffFcBCRbzdw | OKFfl58XVQMrAyC
126 | CwvkffFcBCRbzdw | dlH8udyTjNV3nXM
142 | 2vu1eqTCWVjgE58 | Q01Iz3lC2uUMBSB
143 | 2vu1eqTCWVjgE58 | vB5s8hfTaVtx3wO
144 | 2vu1eqTCWVjgE58 | 5O9HA5Z7wVhgi6l
145 | 2vu1eqTCWVjgE58 | OiEUOXNjK2D2s8F
I am trying to output with the following information.
The problem I am having is the Group Size column getting it to output a count.
Studentid | Groupid | Group Size
wTsBSkkg4Weo8R3 | PZV7cUZCnLwNkSS | 2
aIuDhxfChg3enCf | PZV7cUZCnLwNkSS | 2
hEwLxJmnJmZFAic | CwvkffFcBCRbzdw | 3
OKFfl58XVQMrAyC | CwvkffFcBCRbzdw | 3
dlH8udyTjNV3nXM | CwvkffFcBCRbzdw | 3
I have researched if I can you can use a where clause in the count, and does not seem like it will let me do that. I thought about doing a sum but couldn't make that happen either. I feel like I am missing something simple.
An easy way to solve this, is using a JOIN statement:
SELECT a.studentid AS Studentid, a.groupid AS Groupid, COUNT(*)
FROM table AS a
JOIN table AS b ON a.groupid = b.groupid
GROUP BY a.studentid, a.groupid
So here we join the table with itself and use a GROUP BY to group on the studentid and groupid and then use COUNT(*) to count the number of rows in b that have the same groupid.
Try this:
SELECT *
FROM pony a
LEFT JOIN (
SELECT COUNT(*), groupid
FROM pony
GROUP BY groupid
) b ON a.groupid = b.groupid
try this
SELECT T1.Studentid, T1.Groupid, T2.GroupCount
FROM Your_Table T1
INNER JOIN ( SELECT Groupid, count(*) AS GroupCount FROM Your_Table GROUP BY Groupid ) T2
ON T1.Groupid = T2.Groupid
You should try:
SELECT COUNT(Groupid) AS Groupsize FROM table;
It seems that what you're trying to do is simple. If I understand correctly, a simple SELECT COUNT statement. To exclude multiple returns of the same value, use SELECT DISTINCT COUNT()

How to write this MYSQL Query with count

So i have the following table:
userid | name | referralcode
When users register on the website they put the referralcode of someone else (the referral code is the same number as the userid of someone else)
so im looking for a sql query that will output something like this
20 (this means 20 users have this userid on their referral code) , Gerardo Bastidas, Valencia
10 , Juan Bastidas, Valencia
I want to get all info on user. its all located in the same table.
Try this query:
SELECT yt1.*, COALESCE(yt2.referral_count, 0)
FROM yourtable yt1 LEFT JOIN
(
SELECT t1.userid, COUNT(*) AS referral_count
FROM yourtable t1 INNER JOIN yourtable t2
ON t1.userid = t2.referralcode
GROUP BY t1.userid
) yt2
ON yt1.userid = yt2.userid;
This query does a self-join and will list every user along with the number of referral codes where his userid appears.
This code will do the work in one query. Replace your table name with 'tbName'
Tested and working
SELECT countval, userid, email, address
FROM tbName t1 LEFT JOIN
(
SELECT COUNT(t2.userid) ASs countval, tt.userid AS xx
FROM tbName t2
GROUP BY t2.referralcode
) t3
ON t3.xx = t1.userid
Output:
+-------+-----+------+
| count | uid | name |
+-------+-----+------+
| 3 | 1 | abc |
| 2 | 2 | xyz |
| 5 | 3 | kmn |
+-------+-----+------+

MySQL: Group By multiple fields and count

This type of question is answered in post "MySQL: Group By & Count Multiple Fields"
EDIT : Sample Query Used
SELECT actors.id AS actor_id, actors.act_name AS actor_name, details.registration_id AS
registration from games INNER JOIN actors ON actors.id = games.actor_id INNER JOIN
details ON details.id = games.detail_id WHERE 'some cond' GROUP BY registration, actor_id;
But, I'm unable to achieve it in my case. My table data is little different (I'm grouping the table by registration, actor_id). eg:
actor_id | actor_name | registration
----------------------------------------
189 | ABC | 1234-1234
189 | ABC | 4567-1234
189 | ABC | 7890-4321
169 | DEF | 1111-5643
169 | DEF | 1111-5643
and I expect the output as below
actor_id | actor_name | registration | actor_count
------------------------------------------------------
189 | ABC | 1234-1234 | 3
189 | ABC | 4567-1234 | 3
189 | ABC | 7890-4321 | 3
169 | DEF | 1111-5643 | 2
169 | DEF | 1111-5643 | 2
That is actor ABC has 3 occurrences in table and DEF has 2 occurrences, etc
Instead when I use count(*) I get an expected count of 1 in each row
But, Is there a way to achieve the above output?
You could achieve this by doing a sub query to the same table. Maybe something like this:
SELECT
actors.actor_id,
actors.actor_name,
actors.registration,
(
SELECT
COUNT(*)
FROM
actors AS innerActors
WHERE innerActors.actor_id=innerActors.actor_id
) AS actor_count
FROM
actors
You can achive your goal by joining your base table to an aggregation subquery (in mysql).
For example:
SELECT
A.actor_id, A.actor_name, A.registration, B.actor_count
FROM
YourTable AS A
INNER JOIN (
SELECT
actor_id, COUNT(1) AS actor_count
FROM
YourTable
GROUP BY
actor_id
) B
ON A.actor_id = B.actor_id
Write a subquery that gets the count for each actor. Then join this with the original table to put the count on each of their rows.
SELECT t1.actor_id, t1.actor_name, t1.registration, t2.actor_count
FROM YourTable AS t1
JOIN (SELECT actor_id, COUNT(*) AS actor_count
FROM YourTable
GROUP BY actor_id) AS t2 ON t1.actor_id = t2.actor_id
DEMO
If you include registration in the grouping, you'll get counts of 1 because the registration is different on each row.

Aggregate functions conflict with some column in my query

I have two tables :
users:
___________________________
|user_id | username |
|_______________|___________|
| 1 | Dolly |
| 2 | Didi |
|_______________|___________|
forum:
_____________________________________________________________
|match_static_id| comment | timpstamp | user_id |
|_______________|___________|______________________|__________|
| 1 | Hi | 2013-07-10 12:15:03 | 2 |
| 1 | Hello | 2013-07-09 12:14:44 | 1 |
|_______________|___________|______________________|__________|
this query is working fine and it uses just thw forum table:
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp'
FROM forum
GROUP BY forum.match_static_id
Order BY timestamp DESC
But the following query is using two tables :
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp', users.username
FROM forum
INNER JOIN users on users.id = forum.user_id
GROUP BY forum.match_static_id
Here I want to get the user of the max(timestamp) but i get the wrong user could any body give my a clue about this, please?
Order BY timestamp DESC
Try this:
SELECT f1.match_static_id,
f2.comments_no,
f2.maxtimestamp,
users.username
FROM forum AS f1
INNER JOIN
(
SELECT match_static_id,
max(timestamp) maxtimestamp,
count(comment) AS comments_no
FROM Forum
GROUP BY match_static_id
) AS f2 ON f1.match_static_id = f2.match_static_id
AND f1.timestamp = f2.maxtimestamp
INNER JOIN users on users.user_id = f1.user_id;
See it in action here:
SQL Fiddle Demo

show results with biggest count mysql

I need to show user with the most comments. I have two tables:
Table: Users
ID | USERNAME | EMAIL
------------------------------
1 | USER01 | EMAIL01
2 | USER02 | EMAIL02
3 | USER03 | EMAIL03
4 | USER04 | EMAIL04
Table: Comments
ID | AUTHOR | COMMENT
----------------------------------
1 | USER01 | COMMENT...
2 | USER02 | COMMENT...
3 | USER01 | COMMENT...
4 | USER03 | COMMENT...
In this example the user01 have the most comments, but lets say I have to result them all with count of comments they have. And also in result I have to show users email which is stored in Users table.
How can I count and at same time check in both tables to return result? Or should I first get user info and then count ?
this query below handles duplicate rows having the most number of comments,
SELECT a.userName
FROM Users a
INNER JOIN Comments b
ON a.username = b.author
GROUP BY a.userName
HAVING COUNT(*) =
(
SELECT MAX(totalCount)
FROM
(
SELECT author, COUNT(*) totalCount
FROM comments
GROUP BY author
) a
)
SQLFiddle Demo
SQLFiddle Demo (with duplicate)
but if you want not to handle that, it can be simply done by using ORDER BY and LIMIT
SELECT a.userName, COUNT(*) totalCount
FROM Users a
INNER JOIN Comments b
ON a.username = b.author
GROUP BY a.userName
ORDER BY totalCount DESC
LIMIT 1
SQLFiddle Demo
select username,email,count(*) as cnt
from users, comments
where author = username
group by username
order by cnt desc
limit 1