I am sure I am missing something obvious or the mySQL code I have written for this tool is incorrect.
What I have got is a site that allow people to follow each other. If they are following a user they should see updates from them in their user dashboard.
I have had to tie several tables together in mySQL query to get the relevant information.
Here are the tables
users
ID Username Password
-------------|---------------|------------------
1 User1 UserPass
2 User2 UserPass
3 User3 UserPass
user_details
ID UserID UserPhoto
-------------|---------------|------------------
1 1 User1photo.jpg
2 2 User2photo.jpg
3 3 User3photo.jpg
userstatusposts
UserStatusID UserID status
-------------|---------------|------------------
1 1 Hey My first post
2 2 Woah this is cool
3 3 It doesnt work
followers
followid followerUserID beingFollowedUserID
-------------|---------------|------------------
1 3 1
There are more cols and rows in these tables but this is a basic form for the question.
As you can see from the followers table User3 is following User1 and should therefore be able to see the posts they have made in userstatusposts, the reason user details and users also need tying in is so I can display the users photo and the users username
The SQL I have at the moment that isn't working is:
SELECT * FROM userstatusposts
JOIN followers ON userstatusposts.userid = followers.followeruserid
JOIN users ON userstatusposts.userid = users.id
JOIN user_details ON userstatusposts.userid = user_details.userid
WHERE followers.beingFollowedUserID='$userid'
ORDER BY userstatusposts.userstatusid DESC
LIMIT 10
However this is all tied together wrong as I see the posts of the wrong users when it is implemented in to my PHP code ($userid is the logged in user).
PHP Page:
<?php
$sql = "SELECT * FROM userstatusposts
JOIN followers ON userstatusposts.userid = followers.followeruserid
JOIN users ON userstatusposts.userid = users.id
JOIN user_details ON userstatusposts.userid = user_details.userid
WHERE followers.beingFollowedUserID='$userid'
ORDER BY userstatusposts.userstatusid DESC
LIMIT 10
";
$result = $conn->query($sql);
$rowcount=mysqli_num_rows($result);
if ($rowcount === 0) {
echo '<li style="list-style-type: none;"><p>Your not currently folllowing anyone.</p></li>';
} else {
while($row = $result->fetch_assoc()) {
if ($row['posttype'] == 'message') {
echo '<li style="list-style-type: none;"><img src="userimg/'.$row['userphoto'].'" height="90px" width="90px"><h3>'.$row['username'].'</h3><small>17/06/2014</small><p>'.$row['status'].'</p></li>';
}
else if ($row['posttype'] == 'map') {
echo '<li style="list-style-type: none;"><img src="userimg/'.$row['userphoto'].'" height="90px" width="90px"><h3>'.$row['username'].'</h3><p>has recently added <b>'.$row['status'].'</b> to there travel map</p></li>';
}
else if ($row['posttype'] == 'like') {
echo '<li style="list-style-type: none;"><img src="userimg/'.$row['userphoto'].'" height="90px" width="90px"><h3>'.$row['username'].'</h3><p>has recently liked a trip report called <b>'.$row['status'].'</b></p></li>';
}
else if ($row['posttype'] == 'report') {
echo '<li style="list-style-type: none;"><img src="userimg/'.$row['userphoto'].'" height="90px" width="90px"><h3>'.$row['username'].'</h3><p>has recently shared a trip report called <b>'.$row['status'].'</b></p></li>';
}
else {
echo 'We are currently expirencing a few diffculties';
}
}
}
?>
I am aware there are other cols being used here but they are in the tables listed above I have just left them out for the question.
Any suggestions why my SQL code is bringing back the wrong information, is it something glaringly obvious I have over looked?
Your query returns all the status of followers, not the status of followed.
You should change
WHERE followers.beingFollowedUserID='$userid'
to
WHERE followers.followerUserID = '$userid'
In addition, this is unrelated to your question, but your code has a security problem. You should sanitize $userid first before using it in your query.
$userid = (int)$userid
// .. now $userid is safe to use in $sql
The issue was one of the JOINS was looking to the wrong field.
The SQL should of been:
JOIN followers ON userstatusposts.userid = followers.beingFollowedUserID
So the full statement is
SELECT * FROM userstatusposts
JOIN followers ON userstatusposts.userid = followers.beingFollowedUserID
JOIN users ON userstatusposts.userid = users.id
JOIN user_details ON userstatusposts.userid = user_details.userid
WHERE followers.followerUserID = '$userid'
ORDER BY userstatusposts.userstatusid DESC
LIMIT 10
This was solved by a friend of mine not me, but thought I would share the answer for anyone interested.
Related
I am creating a messaging site, with php and ajax.
there is a problem on getting conversations.
The problem is that whenever two user chat between them there is two distinct rows with id;
example
A and B is chattting and only written 4 messages to each other
messages database is like this
id senderid recieverid
1 a.id b.id
2 b.id a.id
3 b.id a.id
4 a.id b.id
My aim is getting records with this code
SELECT DISTINCT senderid, recieverid from messages WHERE (senderid = '".$pageowner."' OR recieverid='".$pageowner."')
the $pageowner is the user who logged in;
with this method i get two same conversations
a<->b and b<->a
and the code gives me two conversations on the page i want to only get one result;
my whole php code is like this
if(isset($_POST['id'])){
include 'config.php';
$pageowner = $_POST['id'];
$sql = "SELECT DISTINCT senderid, recieverid from messages WHERE (senderid = '".$pageowner."' OR recieverid='".$pageowner."')";
$result = mysqli_query($connect, $sql);
$conversations = mysqli_fetch_all($result);
$output = "";
foreach($conversations as $conversation){
$senderonmessages = $conversation[0];
$recieveronmessages = $conversation[1];
if($pageowner == $senderonmessages){
$convname = $recieveronmessages;
}else{
$convname = $senderonmessages;
}
$sql = "SELECT id, name, surname, userimage FROM users WHERE id='".$convname."' ORDER BY id" ;
$resconv = mysqli_query($connect, $sql);
$user = mysqli_fetch_assoc($resconv);
$output .= '
<div class="conversationuser" id='.$user['id'].'>
<img src="'.$user['userimage'].'">
<span id="status"></span>
<div class="conv-info">
<h4>'.$user['name'].' '.$user['surname'].'</h4>
<p>Axirinici yazdigim mesaj <span id="time">10:34 AM</span></p>
</div>
<div class="conv-additional-info">
<span id="notif">1</span>
<i class="fas fa-ellipsis-v"></i>
</div>
</div>';
}
echo $output;
}
You need to fix your sql injection problem first. If you don't do that, you won't have any data in your database to worry about because somebody will drop it.
https://www.php.net/manual/en/security.database.sql-injection.php
Also, your query gives you exactly what you are asking for: DISTINCT senderid, recieverid
For a solution to your question, I'd create a view that is something like:
create view conversations as
SELECT senderid, recieverid FROM messages GROUP BY 1, 2
UNION
SELECT receiverid, senderid FROM messages GROUP BY 1, 2
Then, you can select from this view and get what you want.
As mentioned in the comment the UNION will give you distinct so you don't even need that...
I created a simple upvote system for my website, I have a little bug where it will not grab all of the ID's that I need for displaying. The issue is that I have multiple repeat values in the database for the ID of each item that the user's voted on.
I created a separate table for the votes so that I can update the arrow color when it has been voted.
Here is the code for displaying the results, it's in a foreach loop:
if(isset($_SESSION['user_session'])){
if(($row['voteLikes_topic'] == $row['topic_id']) && ($row['voteLikes_user'] == $_SESSION['user_session'])){
var_dump($row['voteLikes_topic']);
$returnValues .= '<i class="fa fa-arrow-up"></i> ';
}else{
$returnValues .= '<i class="fa fa-arrow-up"></i> ';
}
}
Here are the columns in the database for the voting results:
Here is the query:
$query = "SELECT
count(replies.reply_topic) as replyCount,
topics.topic_id,
topics.topic_subject,
topics.topic_date,
topics.topic_cat,
topics.topic_picture,
topics.topic_creator,
topics.topic_likes,
users.user_id,
users.username,
profile.profile_id,
profile.profile_pictureMain,
profile.profile_users,
savelink.saveLink_id,
savelink.saveUser_id,
savelink.link_id,
votelikes.voteLikes_user,
votelikes.voteLikes_topic,
votelikes.voteLikes_hot,
votelikes.voteLikes_cold
FROM
topics
LEFT JOIN
users
ON
topics.topic_creator = users.user_id
LEFT JOIN
replies
ON
replies.reply_topic = topics.topic_id
LEFT JOIN
profile
ON
profile.profile_users = users.user_id
LEFT JOIN
savelink
ON
savelink.link_id = topics.topic_id
LEFT JOIN
votelikes
ON
votelikes.voteLikes_topic = topics.topic_id
GROUP BY
topics.topic_id
ORDER BY
topics.topic_date DESC
LIMIT ?, ?
";
And here is what the query is displaying (for clarity)
So what is happening right now is that once it grabs the 'voteLikes_topic' value of say 66 for the 'voteLikes_user' ID of 41 then if I log in with voteLikes_user ID of 6 and it also has a value in the column of voteLikes_topic 66, it won't display the second value in the database.
Simply put: since 'voteLikes_topic' value of '66' came first with 'voteLikes_user' value of '41', then the voteLikes_topic value of 66 won't display for voteLikes_user value of 6.
I know it's a simple query problem but I am not finding it. Thanks in advance.
I have a mysql table consisting of users following other users.
USER_ID FOLLOW_ID
1 2
1 3
2 4
3 4
6 4
2 6
I am user No. 2 and the person in question is user No. 4. You see that three people are following user No.4 including me. I can query the users who are following user No.4. How can I add to the query if I am following these people or not? So what I would like to know is who are following a specific user (No.4 in this case) and which one of them I am following.
Desired result:
USER_ID (No.4 is FOLLOWED BY), DO_I_FOLLOW_HIM
2 No
3 No
6 Yes
As you see from the last record of the table I (No.2) am following User No.6.
Query the list of people following user No.4:
$myid = '6';
$userid = '4';
$i = 0;
try {
$stmt = $conn->prepare("SELECT USER_ID FROM FOLLOW WHERE FOLLOW_ID=?");
$stmt -> execute(array($userid));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$row2[$i] = $row['USER_ID'];
$i++;
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
$response["success"] = 0;
}
Sample SQL Fiddle for help: http://sqlfiddle.com/#!2/97ac6
SELECT him.user_id, IF(i.follow_id,'yes','no') AS i_follow_him
FROM Follows him
LEFT JOIN Follows i ON (i.follow_id = him.user_id AND i.user_id = 2)
WHERE him.follow_id = 4
To get a list of users that you follow that are following another given user, you need to use a subquery. You can see it when written above you are asking two things
Who is following person A
From that list who am I following.
So You could try using a query like so,
Select User_ID, Follows_ID
From Follows
Where User_ID = ?
And Follow_ID In (Select User_ID From Follows Where Follow_ID = ?)
To see a list and whether you're following
Select f.User_ID,
Case When ? In (Select User_ID From Follows Where Follow_ID = f.User_ID) Then 'Yes' Else 'No' End
From Follows f
Where f.Follow_ID = ?
#Shudder makes a good point, you may see performance increases (especially if this is a large table) by using a join instead of a subquery.
SELECT him.user_id, IF(i.follow_id,'yes','no') AS i_follow_him
FROM Follows him
LEFT JOIN Follows i ON (i.follow_id = him.user_id AND i.user_id = ?)
WHERE him.follow_id = ?
I made it easier by adding your own id and user No 4.
select follow_id
from follows
where user_id=2 and follow_id IN (select user_id from follows where follow_id=4)
I just need help refining this script to give me the values from both tables joined on the ID.
Basically I want the ID from both tables and then be able to get the other values from both tables based on the IDs (if need be) and display them in a loop.
The code I have is below but won't work.
$select = myQ("SELECT * FROM users a WHERE EXISTS (SELECT 1 FROM `videos` b WHERE a.id = b.id GROUP BY b.id HAVING count(*) > 1) ");
$i=0;
while ($row = myF($select)) {
$resultsLoopArray[$i]["videos.id"] = $row["id"];
$resultsLoopArray[$i]["videos.vid"] = $row["vid"];
$resultsLoopArray[$i]["users.username"] = $row["username"];
$i++;
}
if (isset($resultsLoopArray)) {
$tpl->Loop("searchResultsLoop", $resultsLoopArray);
}
For now all I need is the username from the users table, the id and video id from the video table.
Can someone help by chance?
you question is bit confusing me..
As for my understanding I am posting this soultion..
If you have two tables users , videos then .
$sql = "SELECT users.username , videos.* from users, videos where users.user_id = videos.user_id";
this query will fetch all record from users and videos table where user id is present in videos tables ...
I have a query that retrieves the name of each friend a user has by joining that of friends and users tables. I have another table that stores active users. I need to retrieve friends that are active and not active but for some reason I am drawing a blank. If I have a list of all friends and a list of active friends, can I subtract active from all to be left with offline? All I Want to do basically is have two tabs. Under one will be offline friends. Under the other will be online friends. If anyone has any useful suggestions, I would appreciate it.
$sql = 'SELECT * FROM users
LEFT JOIN friendships
ON friendships.friend_id = users.id
WHERE friendships.user_id = ?';
$stmt5 = $conn->prepare($sql);
$result=$stmt5->execute(array($userid));
$count=$stmt5->rowCount();
//user has more than 0 friends
if ($count>0){
while ($row = $stmt5->fetch(PDO::FETCH_ASSOC)) {
$online=htmlspecialchars( $row['username'], ENT_NOQUOTES, 'UTF-8' );
//check whos online
$sql = 'SELECT * FROM active_users
WHERE username=?';
$stmt7 = $conn->prepare($sql);
$result=$stmt7->execute(array($online));
$count=$stmt7->rowCount();
while ($row = $stmt7->fetch(PDO::FETCH_ASSOC)) {
$activeuser=$row['username'];
}
}
This code just retrieves active users but hopefully gives an idea of structure.
Could you do a "not in" clause? Without knowing the layout of your database, I'm thinking something like this:
SELECT * FROM users
LEFT JOIN friendships
ON friendships.friend_id = users.id
WHERE friendships.user_id = ?
AND users.id NOT IN (
SELECT user_id FROM active_users
)
Using SQL to do this 'not in' is probably the best solution.
You could also do this in code if you really want to if the results are ordered. Just loop through the all users list, grab the first result from the active users list, and whenever there's a match, put that on the active users list and grab the next active user. Put every non-match into the inactive users list and only fetch from the all users list.
Something like this might tell you both lists in one shot:
SELECT users.username, active_users.username AS active FROM users
LEFT JOIN friendships
ON friendships.friend_id = users.id
LEFT JOIN active_users ON users.username = active_users.username
WHERE friendships.user_id = ?
Inactive users would return NULL in the active columns, where active would not.