How to count messages for a user with php and mysql - php

I'm trying to count number of messages each user got. I have a users with user's detail id, name etc. I have created another table users_msgs where I have id, msg_id, user_id. I want to display count of messages each user got. what will be the best way to do it?
The web application have more than 2000 users. so the script have to select all of them and count their messages. I think this is not the best solution.
I thinking of count rows for 1 user from users_msgs table as count and then querying the users table for user's name with his id from users_msgs table.
I have tried selecting all users without any limit:
SELECT * FROM users
then iterating over the results like so:
<?php
while ($user = mysqli_fetch_assoc($users)) {
$count = count_user_msgs($user['id']);
echo "{$user['name']} messages: $count";
}
?>
The count_user_msgs function looks like this:
<?php
$sql = "SELECT COUNT(id) as msgs_count FROM users_msgs WHERE user_id = ?";
$stmt = mysqli_stmt_init($db);
if (mysqli_stmt_prepare($stmt, $sql)) {
mysqli_stmt_bind_param($stmt, 's', $user_id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$count = mysqli_fetch_assoc($result)['msgs_count'];
return $count;
}
return false;
?>

You need to group by each user and get the count:
$sql = "SELECT user_id, name, count(user_id) as msgs_count from table group by (user_id, name)";
$result = $mysqli->query($query)
while ($user = mysqli_fetch_assoc($users)) {
$user_id = $users['user_id'];
$msgs_count= $users['msgs_count'];
$count[$user_id] = $msgs_count;
echo "{$user['name']} messages: $msgs_count";
}

FWIW, You can get it in a single query...
SELECT u.name, count(m.user_id) message_count
FROM users u
LEFT JOIN users_messages m ON u.user_id=m.user_id
GROUP BY m.user_id, u.name

You want to count the number of msg_ids per user_id, so you'll want to GROUP BY user_id and count msg_id, like this:
$sql = "SELECT COUNT(msg_id) as msgs_count FROM user_msgs WHERE user_id = ? GROUP BY user_id";
The GROUP BY might not be necessary.

Related

Get applicants from Table 1 and compare id and get user details from Table 2 Using PHP

Ok so I have two Tables
Applicant list - this shows all applicants
User Table
Now I'm Providing news_id by Post method and I want to list details of all users(email,mobile,username) where the value for user_authToken and user_authtoken is same. Can Someone help me out with this logic using PHP.
$job_id = $_POST['job_id'];
$resultSet = $con->query("SELECT appliers_list.news_id AS jobid ,
appliers_list.user_authToken AS user,
user.user_name AS username,
user.mobile AS mobile,
FROM appliers_list,user
WHERE appliers_list.news_id = '$job_id'
ORDER BY appliers_list.id DESC
");
$rows = $resultSet->fetch_assoc();
First of all, your naming is very inconsistent, it's hard to read and understand.
Second, please use prepare statement, otherwise you open your system to SQL injection.
$news_id = $_POST['job_id'];
$stmt = $con->prepare("SELECT email, mobile, user_name
FROM users
WHERE user_authtoken in (select user_authToken from appliers_list where news_id = ?)");
$stmt->bind_param("i", $news_id);
$stmt->execute();
$resultSet = $stmt->get_result();
while($row = $resultSet->fetch_assoc()) {
// data manipulation here
}
you can use left join to get record from both table :
$job_id = !empty($_POST['job_id']) ? intval($_POST['job_id']) : 0;
$resultSet = $con->query("SELECT appliers_list.*,users.email
FROM appliers_list
left join users on appliers_list.user_authToken = users.user_authToken
WHERE news.news_id = '$job_id'
ORDER BY news.id DESC
");
$rows = $resultSet->fetch_assoc();
You didn't specify a relationship between the user and appliers_list tables, so you're getting all rows in user. You also have an extra comma at the end of the SELECT list.
$job_id = $_POST['job_id'];
$resultSet = $con->query("SELECT appliers_list.news_id AS jobid ,
appliers_list.user_authToken AS user,
user.user_name AS username,
user.mobile AS mobile
FROM appliers_list
JOIN user ON appliers_list.user_authToken = user.user_authToken
WHERE appliers_list.news_id = '$job_id'
ORDER BY appliers_list.id DESC
");
$rows = $resultSet->fetch_assoc();

Deleting a row with inner join

I've created two tables, simplecomments and commentors, and connected them with INNER JOIN.
Simplecomments is details of each and every commenter, involving their comment, reg_date, commentorid etc...
Commentors is the personal info of a commenter with following columns: id, name, email..
I've joined them successfully, however I'm finding it hard to delete from the joined table.
I want to make it like this logic:
If there's last row of a commentor called --let's say A-- then delete both his/her comment details and A himself/herself from the table.
Else if A has commented plenty of times, with different comments, delete his/her comment details, but let his/her personal info remain since A has other comments there.
This is how I've made it:
if (!empty($_POST["delete"]))
{
foreach ($_POST["delete"] as $key => $value)
{
$resultid = $conn->query("SELECT commentorid FROM `simplecomments` WHERE id=".$value);
$rowid = $resultid->fetch_assoc();
$outputdelete = $rowid["name"] . " has been deleted" . "<br>";
$deletedname = $deletedname.$outputdelete;
$RES = mysql_num_rows($resultid);
$counter = 0;
while($row = $RES)
{
//IF IT'S LAST ROW, DELETE COMMENTOR AND HIS/HER COMMENTDETAILS
if(++$counter == $results) {
$resultid = $conn->query("DELETE FROM `commentor`");
}
//ELSE JUST DELETE HIS/HER COMMENTDETAILS, LET HIS/HER INFO REMAIN
else{
$resultid = $conn->query("DELETE FROM `simplecomments` WHERE id=".$value);
}
}
}
}
However code won't work. I get an error:
Warning: mysql_num_rows() expects parameter 1 to be resource [..]...
Consider running DELETE...INNER JOIN and DELETE with subquery conditionals and avoid PHP query fetch looping with if/else as the logic seems to be the following:
delete any commentor's profile and comments if he/she has only one comment
delete only commentor's comments if he/she has multiple (i.e., more than one) comments.
And yes, all three DELETE can be run at same time across all ids since mutually exclusive conditions are placed between the first two and last one. Therefore, either first two affects rows or last one affects rows per iteration. The unaffected one(s) will delete zero rows from either table.
Also, simplecomments records are deleted first since this table may have a foreign key constraint with commentor due to its one-to-many relationship. Finally, below assumes comment ids are passed into loop (not commentor id).
PHP (using parameterization, assuming $conn is a mysqli connection object)
foreach ($_POST["delete"] as $key => $value) {
// DELETE COMMENTS AND THEN PROFILE FOR COMMENTORS WITH ONE POST
$sql = "DELETE FROM `simplecomments` s
WHERE s.id = ?
AND (SELECT COUNT(*) FROM `simplecomments` sub
WHERE sub.commentorid = s.commentorid) = 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $value);
$stmt->execute();
$stmt->close();
$sql = "DELETE c.* FROM `simplecomments` c
INNER JOIN `simplecomments` s ON s.commentorid = c.id
WHERE s.id = ?
AND (SELECT COUNT(*) FROM `simplecomments` sub
WHERE sub.commentorid = s.commentorid) = 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $value);
$stmt->execute();
$stmt->close();
// DELETE COMMENTS FOR COMMENTORS WITH MULTIPLE POSTS BUT KEEP PROFILE
$sql = "DELETE FROM `simplecomments` s
WHERE s.id = ?
AND (SELECT COUNT(*) FROM `simplecomments` sub
WHERE sub.commentorid = s.commentorid) > 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $value);
$stmt->execute();
$stmt->close();
}
Alternatively, for a DRY-er approach, loop SQL statements in an array:
$sqls = array(
0 => "DELETE FROM `simplecomments` s WHERE s.id = ? AND (SELECT COUNT(*) FROM `simplecomments` sub WHERE sub.commentorid = s.commentorid) = 1",
1 => "DELETE c.* FROM `simplecomments` c INNER JOIN `simplecomments` s ON s.commentorid = c.id WHERE s.id = ? AND (SELECT COUNT(*) FROM `simplecomments` sub WHERE sub.commentorid = s.commentorid) = 1",
2 => "DELETE FROM `simplecomments` s WHERE s.id = ? AND (SELECT COUNT(*) FROM `simplecomments` sub WHERE sub.commentorid = s.commentorid) > 1"
);
foreach ($_POST["delete"] as $key => $value) {
foreach($sqls as $sql) {
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $value);
$stmt->execute();
$stmt->close();
}
}

How can I summarize total amount

How can I summarize total amount of users earning from a column "price" values?
$statement = "SELECT user_id, SUM(price) FROM tbl_post WHERE user_id= ".'$_SESSION['user']';
$statement = mysql_query($statement);
$user_earning= mysql_fetch_row($statement);
echo $user_earning;
you should add GROUP BY clause at select statment
$statement = "SELECT user_id, SUM(price)
FROM tbl_post
WHERE user_id= ".'$_SESSION['user']". "
GROUP BY user_id";
write above query instead of this query
$statement = "SELECT user_id, SUM(price) FROM tbl_post WHERE user_id= ".'$_SESSION['user']';
i dont know about php but by see your query you want to sum of all price of a perticular user.
Try this, you have error in your query :
$statement = "SELECT user_id, SUM(price) FROM tbl_post WHERE user_id= '".$_SESSION['user']."' ";
$statement = mysql_query($statement);
$user_earning= mysql_fetch_row($statement);
echo $user_earning[1];// echo $user_earning['price'];
Your SQL query should look like that:
select user_id,sum(price) from tbl_post where user_id=? group by user_id;

sql select from table then compare with other table in one statement

I have to tables in one database.
users
user_activate
I have to variables in php
$username = foo;
$key = jas823k123ksd34324;
Now I want to select from the table users the attribute user_id where user_username == $username
I do this with this statement
$sql = "SELECT user_id FROM users WHERE user_username = '$username'";
$result = mysqli_query($db, $sql);
while($row = mysqli_fetch_assoc($result)){
$user_id = $row['user_id'];
}
Now I want to select from the table user_activate the attribute user_activate_key where user_activate_key == $key;
For this I use this statement:
$sql2 = "SELECT user_activate_key FROM user_activate WHERE user_activate_key = '$key'";
$result2 = mysqli_query($db, $sql2);
while($row = mysqli_fetch_assoc($result)){
$user_key = row['user_activate_key'];
}
Can I do both statements in one statement?
As you've written it, two seperate queries is the correct way to do it. But I suspect that there's some kind of relationship between users and user_activate that might make what you're asking for make sense. Assuming that a user_activate_key is tied to a specific user_id, you could do something like the following:
select users.user_id, ua.user_activate_key
from users u
left join user_activate ua
on u.user_id = ua.user_id
and ua.user_activate_key = '$key'
where u.username = '$username'
The LEFT JOIN means that the user will be shown even if there isn't a matching user_activate_key record.

Looping through a mysqli result

I'm trying to display a list of status updates from artists that a logged in user is following.
So far I have this:
#Get the list of artists that the user has liked
$q = "SELECT * FROM artist_likes WHERE user_id = '1' ";
$r = mysqli_query($dbc,$q);
while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
#Now grab the statuses for each artist
$status_query = "SELECT * FROM status_updates WHERE artist_id = '".$row['artist_id']."' ";
$status_result = mysqli_query($dbc,$status_query)
}
But i'm not sure how to loop through and display the returned status updates?
This isn't a strong point of mine, so any pointers would be greatly appreciated!
What prevented you from doing similar to what you'd already done for the first query? Something like follows:
#Get the list of artists that the user has liked
$q = "SELECT * FROM artist_likes WHERE user_id = '1' ";
$r = mysqli_query($dbc,$q);
while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
#Now grab the statuses for each artist
$status_query = "SELECT * FROM status_updates WHERE artist_id = '".$row['artist_id']."' ";
$status_result = mysqli_query($dbc,$status_query)
while($status_result_row = mysqli_fetch_assoc($status_result)) {
echo $status_result_row['mycol']; // This is where you know better than us
}
}
Or if those two tables artist_likes and status_updates have artist_id in common then you could just use one query with a join. (But don't know if you are asking for that).
Just for avoiding multiple query, you can use one query like this:
SELECT l.*, s.*
from artist_likes l, status_updates s
WHERE
l.artist_id = s.artist_id and
l.user_id = '1'
or
SELECT l.*, s.*
from artist_likes l
JOIN status_updates s on (l.artist_id = s.artist_id)
WHERE
l.user_id = '1'

Categories