In MySQL how do I count messages from a user? - php

I have tables as below.
Table Messages
message_id
parent_id
forum_id
user_id
Table Users
user_id
username
pass
How to query a user, and display the count of their messages with their username?
My query:
select count(subject), user_id from messages group by user_id;
The problem is that it only displays user_id and count of messages but no username. How do I make it display the name of the user?

You need to join the users table into your query:
select count(*), username
from messages, users
where users.user_id = messages.user_id
group by users.user_id;

SELECT username, COUNT(*) FROM messages M
JOIN users U USING (user_id)
GROUP BY U.user_id
This takes care of a scenario where two different user_id have the same username in the users table. Also this query is MySQL specific and may not work with other RDBMS.

I think this is the query you want.
$query = "SELECT u.username, COUNT(*) as total_count FROM messages m INNER JOIN users u ON m.user_id = u.user_id GROUP BY U.user_id"
Here total_count gives the total count of messages grouped by user id to avoid joining of same usernames.

Use below. I believe it will work.
SELECT messages.user_id, users.username, count(*)
FROM messages, users
WHERE messages.user_id = users.user_id
Good Luck!!!

Related

SQL Order By Column From another Table

$sql = "SELECT user2 FROM subscriptions WHERE user1 = '$username'";
This code works perfectly, but what I would like to do is ORDER it BY a column from my users table, the user_id column. Now I can't do this…
$sql = "SELECT user2 FROM subscriptions WHERE user1 = '$username' ORDER BY user_id";
Because there is no column called user_id in my subscriptions table, just in my users table.
I can't understand why you have two user columns, maybe it's a typo. But you need to JOIN the tables. In this case I've used a LEFT OUTER JOIN which will only return records from subscriptions and what matches the JOIN condition from users. i.e. user2 = user_id.
SELECT subscriptions.user2
FROM subscriptions
LEFT JOIN users ON subscriptions.user2 = users.username
WHERE subscriptions.user1 = '$username'
ORDER BY users.user_id
You can select the user_id in your ORDER BY clause:
SELECT user2
FROM subscriptions
WHERE user1 = '$username'
ORDER BY (select user_id from users where users.username = subscriptions.user2);
I surmise that users.username is unique, so you have two natural unique keys in your users table (user_id and username). You've decided to use username for references in other tables. That is okay.
If, however, users.username is not unique, then your databse design is broken and you should use the user_id as reference in other tables instead of username, of course.
Use regular join (not LEFT JOIN) if you have one-to-one data relation.
SELECT a.user2 FROM subscriptions a, user b
WHERE a.user2 = b.username
AND a.usera.user1 = '$username' ORDER BY b.user_id
This is hard to give working solution without viewing table's scheme. But from the query it's looks like you have poor dab design if you use '$username' to search in subscriptions instead of users table.
With an good database design your query should be like this:
SELECT a.fiel1, a.field2, a.user_id, b.field1, b.field2, b.user_id
FROM subscriptions a, user b
WHERE a.user_id = b.user_id
AND b.username = '$username' ORDER BY b.user_id
Joins by user_id
Storing username once in users table
Use user_id in any other tables
You should use JOIN syntax and after you can order by user_id from the users table.
u should use order by user_id desc

MySQL Foreign Keys.. confused

I am trying to understand MySQL Foreign Keys, I hope someone can help.
I have two tables with the following structures;
reports
+-----------+------+-----------+------------------+
|id|user_id |status|report_type|request_id |
+-----------+------+-----------+------------------+
| |
+-------------------------------------------------+
users
+-----------+------+-----------+------------------+
|id|username|f_name|l_name |email |
+-----------+------+-----------+------------------+
| |
+-------------------------------------------------+
I have a foreign key in the reprots table (fk_uid) that links the user_id column in the reports table to the id in the users table.
I want to run a MySQL Query in PHP that will pull all the reports for a given user (either by username or user_id, not sure which is best?)
Thanks!
It could be done by simple inner join as
select
users.username,
users.f_name,
users.l_name ,
reports.status,reports.report_type,
reports.request_id from reports
inner join users on users.id = reports.user_id
If you want to search for a specific user then use where condition as
select
users.username,
users.f_name,
users.l_name ,
reports.status,
reports.report_type,
reports.request_id from reports
inner join users on users.id = reports.user_id
where users.username = 'some user name'
And if you want by userid then where condition is
where users.id = 'your user id'
if you only want to get reports and no user information then you can do a direct query to reports table if you have a user_id
Suppose you have userid in a variable in $userid
like
select * from reports where user_id = $userid
if you want data from both tables then you need to do a join like this
Reports for a specific user:
select r.*, u.* from reports r, users u where r.user_id = $userid
and r.user_id = u.id
Reports for all users
select r.*, u.* from reports r, users u where r.user_id = u.id
if you want to learn more about joins the visit this link
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
http://www.sitepoint.com/understanding-sql-joins-mysql-database/

PHP MySQL Active Record criteria sum

I have two tables, users and visits. I want to select all users who have 'active' in the visits table's status field, with a count of all visit records regardless of active/inactive status.
This query would only give me a count of 'active' visit records
SELECT
users.user_id,
COUNT(visits.id)
FROM users u
JOIN visits v ON v.user_id=u.user_id
WHERE visits.status='active'
I was thinking of a subquery, or a php loop but worried about performance if the users table grows. If subquery's the best solution please post the active record code.
A sub-query will be more efficient than looping in the code. I'd suggest this query:
select u.user_id, ucount
from users u
join (
select user_id, COUNT(id) as ucount
from visits
group by user_id
) all
ON u.user_id = all.user_id
join visits v
on v.user_id=u.user_id
where v.status='active'
And if you need only user_id and no users.* field, then you don't have to join to users table (inspired by answer from arunmoezhi):
select user_id,count(*) as visit_count
from visits v
join (
select user_id from visits
where status ='active'
) act
on v.user_id=act.user_id
group by v.user_id;
Edited for formatting.
select user_id,count(*) as visit_count
from visits
where user_id in(
select user_id from visits
where status ='active'
)
group by user_id;

How to find total of records?

how can I find the total records in this case:
I have a table 'users', a table 'messages' and a table 'groups'. A user can sent a message, and that will be stored in the table 'messages'. Each user can be a member of one group. Now I would like to show the total messages sent by all users in the group on the group-details-page. How can I get all the users in the group and count their messages? What is the best and fastest way to do that?
I can't work with Joins, so this doesn't work. I don't know how to fix it.
SELECT COUNT(Message_id) AS total_messages, d.Userid FROM messages AS
d LEFT JOIN users AS s ON (s.Groupid=$groupid) WHERE
s.Groupid=$groupid
Thanks!
If you need table structure:
** users **
Userid
Groupid
** groups **
Groupid
Some_details
** messages **
Messageid
Userid
Subject
Content
If you're looking for total messages without needing to know per user, try
SELECT COUNT(messages.Messageid) as total_messages
FROM messages
INNER JOIN users ON messages.Userid = users.Userid
WHERE users.Groupid = $groupid
Make sure you're indexing the messages.Userid field as well if you'll be doing a lot of querying based on it.
Needing a count per user try
SELECT
COUNT(messages.Messageid) as num_messages,
messages.Userid
FROM messages
INNER JOIN users ON messages.Userid = users.Userid
WHERE users.Groupid = $groupid
GROUP BY users.Userid
If you want all users in a particular group with their total messages then try out this
SELECT messages.Userid, COUNT(messages.Messageid) as total_messages
FROM messages
INNER JOIN users ON messages.Userid = users.Userid
WHERE users.Groupid = $groupid GROUPBY messages.Userid
Select Groupid,Some_details,count(Messageid) as count_message from groups Left join users On
users.Groupid = groups.Groupid left join messages on messages.Userid = users.users.Userid GROUP BY Groupid

SELECT statement inside another SELECT statement

I have two tables called messages and users. In the messages table, there's a field which is a foreign key to the users table that is basically the users ID. I am trying to retrieve results from the messages table using a SELECT query, but I want the users username rather than their user ID. This SQL is wrong but I think it gets across the idea of what I'm trying to do:
SELECT (SELECT username FROM `users` WHERE u_id=?), message, sent FROM `messages` WHERE r_id=? AND sent > ?
Basically, I want to use the users ID stored in the messages table to get the users username to be returned AND get results from the messages table in one query.
I think JOINs are the tool for this, but I have very little bar no SQL experience.
Thanks.
You want to JOIN the two tables together, using the common u_id column.
SELECT u.username, m.message, m.sent
FROM messages m
INNER JOIN users u
ON m.u_id = u.u_id
WHERE m.r_id = ?
AND m.sent > ?
This is the case for an inner join:
select
u.username,
m.message,
m.sent
from
messages m
inner join users u on
m.u_id = u.u_id
where
m.r_id = ?
and u.u_id = ?
and m.sent > ?
What you're doing here is taking the messages table and saying, "Okay, grab me everything in the users table where the u_id column from messages equals the u_id column from users.
The where clause then filters your results down based on the parameters you want to pass it.
You can join tables ad nauseum, so you don't have to do just one, for future reference.
If you'd like to read more about joins and the different types, I highly encourage you to read Atwood's post on it here.
You can join two tables like this too:
SELECT
u.username,
m.message,
m.sent
FROM
messages m,
users u
WHERE
m.r_id=? AND
m.sent > ? AND
m.u_id = u.u_id
m.u_id is user id in messages table
You can refactor the query slightly like this:
select
u.username,
m.message,
m.sent
from
(
select u_id,message,sent
from messages
where r_id = ?
and sent > ?
) m
inner join
(
select u_id,username
from users
where u_id = ?
) u using (u_id);
You need to make sure you have a compound index on r_id and sent
ALTER TABLE messages ADD INDEX (r_id,sent);
Your query needs only slight correction and then it's equivalent to a LEFT JOIN (or INNER JOIN, exactly as #Joe Stefanelli's answer if messages.u_id is never NULL):
SELECT
(SELECT username FROM `users` WHERE u_id = messages.u_id) AS username
, message
, sent
FROM messages
WHERE r_id = ?
AND sent > ?

Categories