I'm trying to change my user's news feed to only show posts from friends, instead of from all users on the site. I managed to do so doing something like this:
function friend_posts(){
global $session_user_id;
if(friends_exist($session_user_id) === true){
$friends = mysql_query("SELECT * FROM `friendship` WHERE `user_id` = $session_user_id AND `pending` = 0");
while($friend = mysql_fetch_array($friends)){
$friendID = $friend['friend_id'];
$posts = mysql_query("SELECT * FROM `posts` WHERE `userid` = $friendID ORDER BY `timestamp` DESC");
while($post = mysql_fetch_array($posts)){
$friendData = user_data($post['userid'],'username','first_name','last_name');
echo $friendData['username'].": ".$post['status']."<br>";
}
}
} else {
echo "Nothing to display. Try adding some friends!";
}
}
However, this isn't that convenient. For example, if I want to paginate, I don't know how I'd even start to do that using something like this. Also if multiple users post, how would I sort them by 'timestamp' descending?
I'm guessing the only route I can take is accessing columns from multiple tables somehow, then sorting by the timestamp, which is stored in the posts table. The friendship table just has id, user_id, friend_id and pending.
How would I go about doing that? Is there an easier way to do what I'm trying to do?
I'm very new to SQL. I don't know too much other than inserting/deleting/updating.
You could use a single statement like this:
SELECT * FROM posts WHERE userid in
(SELECT friend_id FROM friendship WHERE user_id = $session_user_id AND pending = 0)
ORDER BY `timestamp` DESC
This way you get only the posts of the friends of the current user. If you also need data from the friendship table then use a join.
Related
I wanted to fetch data from MySQL with PHP when a user inputs something. I have this code.
$query = "SELECT * FROM mealplans WHERE plantitle LIKE '%$inputText%' AND `STATUS` = 1 OR plantitle LIKE '%$inputText%' AND userid = '$userid' GROUP BY plantitle, userid";
$result = mysqli_query($con, $query);
It works fine however, it fetches the oldest or first data from the group. How do I select the newest data?
I've search and found possible solutions by using FROM, JOIN, IN, etc. However, I do not know how to use them since I only know the basics. Hopefully someone could explain one solution for me.
There is a simple solution that you can do.
You can order your data to DESC order. I'm sure that you have an id(primary key) in your table.You just have to order all your datas' to DESC order of ids .So that your last inserted data set will be the one to be fetched since it's on the top.
change your query to: (add your primary key(in the following query i have added it as id) in the ORDER BY syntax)
$query = "SELECT * FROM mealplans WHERE plantitle LIKE '%$inputText%' AND `STATUS` = 1 OR plantitle LIKE '%$inputText%' AND userid = '$userid' GROUP BY plantitle, userid ORDER BY `ID` DESC"
Just add a condition in your query which only retrieves the row having the greatest id.
Find out the id first and then you can use the same query for that id:
SELECT MAX(id) FROM mealplans WHERE plantitle LIKE '%$inputText%' AND `STATUS` = 1 OR plantitle LIKE '%$inputText%' AND userid = '$userid' GROUP BY plantitle, userid
After getting the id and storing it in a variable (say $temp):
SELECT * from mealplans where `id` = $temp
I am currently trying to make a system which selects a user at random from the table 'users' and appends it to another table 'agreeuser' or 'disagreeuser' depending on whether or not the user has the 'opinion' value of 'like' or 'dislike'. I am doing this by using $row to select the full row where the user has the opinion of 'like', but it doesn't seem to be adding the data stored in '$row[username]' to the 'user' column of the 'agreeuser' or 'disagreeuser' table.
I have already tried storing the '$row['username'] value as a variable and using this in the value aspect of the query, but it doesn't seem to have worked. I have also tried combining the INSERT and SELECT queries and it still has no effect. Can anyone tell me what I am doing wrong, please? :)
if($_SESSION['pageLoaded'] != "true") {
$selectLikesQuery = "SELECT * FROM users WHERE opinion = 'like' ORDER BY RAND() LIMIT 1";
$likeSelectorResult = mysqli_query($userConnect, $selectLikesQuery);
while($row = mysqli_fetch_assoc($likeSelectorResult)) {
$removeCurrentAgreeContent = "TRUNCATE TABLE agreeUser";
$addAgreeUserQuery = "INSERT INTO agreeUser (user) VALUE ('$row[username]')";
mysqli_query($chatConnect, $removeCurrentAgreeContent);
mysqli_query($chatConnect, $addAgreeUserQuery);
}
$selectDislikesQuery = "SELECT * FROM users WHERE opinion = 'dislike' ORDER BY RAND() LIMIT 1";
$dislikeSelectorResult = mysqli_query($userConnect, $selectDislikesQuery);
while($row = mysqli_fetch_assoc($dislikeSelectorResult)) {
$removeCurrentDisagreeContent = "TRUNCATE TABLE disagreeUser";
$addDisagreeUserQuery = "INSERT INTO disagreeUser (user) VALUE ('$row[username]')";
mysqli_query($chatConnect, $removeCurrentDisagreeContent);
mysqli_query($chatConnect, $addDisagreeUserQuery);
}
$_SESSION['pageLoaded'] = "true";
}
I need the username from 'users' to be inserted into the 'user' column of 'agreeuser'. Thanks for any help, and apologies if I'm doing something stupid :)
Why don't you use SQL views to just see needed data in "a virtual table", instead of creating duplicate data?
Views is a very helpful feature.
For example, make a SELECT query to find needed rows:
SELECT * FROM users WHERE opinion = 'dislike'
If this select suits you, just add:
CREATE OR REPLACE VIEW v_agreeUsers AS SELECT * FROM users WHERE opinion = 'dislike'
And make the same for users who agree:
CREATE OR REPLACE VIEW v_disagreeUsers AS SELECT * FROM users WHERE opinion = 'like'
To be honest, I don't understand why do you do random select and insert users only one by one.
In case you want to get only one and random user, just run this query after you've already created views mentioned upper:
SELECT * FROM v_agreeUsers ORDER BY RAND() LIMIT 1
SELECT * FROM v_disagreeUsers ORDER BY RAND() LIMIT 1
Good luck! :)
I'm making a notifications widget on my website and I'm trying to make it so that if a notification is marked as read, that notification ID will be inserted into another table (table 'b') along with their username so that it is marked as read. Now the problem that I run into is when displaying all notifications (whether they're read or unread) I don't know how to indicate if the notification exists in the secondary table
The currently SQL query is as follows:
$qry = "SELECT * FROM notifications WHERE (notif_recipient = '$user') ORDER BY notif_date DESC";
What I'd like to do is make the query much more complex in order to indicate if a notification exists in another table, so something along the lines of:
$qry = "SELECT notif_id,notif_message,(CASE SELECT notif_is_read AS '1' WHERE notif_id.notifications = notif_id.notifications_read ELSE SELECT notif_is_read AS '0') FROM notifications WHERE (notif_recipient = '$user') ORDER BY notif_date DESC";
Is something like this possible or is it as preposterous as my lack of ability for writing SQL queries
As Marc B had suggested, I decided to use LEFT JOIN in order to identify which messages currently exist in the secondary table, with my query looking as such:
$qrytest = "SELECT notifications.notif_id,notifications.notif_message,notifications.notif_flag,notifications.notif_poster,notifications.notif_date,notifications_read.notif_read_count FROM notifications LEFT JOIN notifications_read ON notifications.notif_id=notifications_read.notif_id WHERE ((notif_recipient = 'all') OR (notif_recipient = '$id')) ORDER BY notif_date DESC,notif_flag DESC";
This in turn will return the results of my primary table (notifications) and if the same notification id exists in my secondary table, I decided to echo out that table's ID count, if the entry does not exist it will simply return as null
$exists = $row['notif_read_count'];
if ($exists !== ''){
// When NOT returning as null do something
} else {
// When exist returns as null do something
}
I have a table named users and has a user_id, and a table named groups and has a group_id and also have user_id that is a foreign key reference from users's user_id.The situation is here: if the user joined a group, his/her user_id is inserted into table groups. So if the user joined two different groups, the column 'user_id' in table 'groups' will insert two or more same user_id's. Well, I just want to bring the user_id once, either he/she joined two or more groups..
I have no idea how to loop it properly without getting user_id that is the same.... I just want it to loop once...
$query_groups = mysql_query("SELECT * FROM groups");
while ($rows_g = mysql_fetch_assoc($query_groups)) {
$g_user_id = $rows_g['user_id'];
$query_users = mysql_query("SELECT * FROM users WHERE user_id='$g_user_id'");
while ($rows_u = mysql_fetch_assoc($query_users)) {
echo $rows_u['user_id'];
}
}
change your code as follows:
$query_groups = mysql_query("SELECT user_id FROM groups LEFT JOIN users ON users.user_id = groups.user_id GROUP BY groups.user_id");
while($rows = mysql_fetch_assoc($query_groups))
{
echo $rows['user_id'];
}
You are using $rows_g but the variable is namend $rows in the first while loop.
Wrong:
$g_user_id = $rows_g['user_id'];
Correct:
$g_user_id = $rows['user_id'];
But try to use joining tables, because this is an inefficient way to get the wanted data.
In your case you should use LEFT JOIN.
I'm working on the photo section of my website, but more precisely on the next/previous link with sorting options.
There are two different option for sorting that exist, first there is a filter (Latest, Trending, Favorite, User etc.) and secondly a sorting option for some of the previous filters (date, views, ratings etc.)
I am having trouble finding a good solution for easily retrieving the next/previous picture for my slideshow.
This is the little bit of SQL I have for getting the next picture for a filter:latest
if ($filter == "latest") {
$sql = "SELECT *
FROM photos
WHERE status = 0 AND id < ".$id."
ORDER BY id DESC
LIMIT 1
";
$result = $db->sql_query($sql);
$sql2 ="SELECT *
FROM photos
WHERE id = (SELECT MAX(id) FROM photos WHERE status = '0')
ORDER BY id DESC
LIMIT 1
";
}
I am wondering if there is an easier way to implement this in my project ? maybe a php class exists to do something like this ?
I feel like I'm going to spend a long time getting all these SQL queries to work properly if I have to do it all like this.
Edit
This is the layout of my photos table
`id` -> unique ID, autoincremented
`title`
`img_name` -> contains the image file name
`date_created` -> when the picture was uploaded
`uploader` -> id of the user that uploaded
`views` -> number of views the picture has
`up_votes` -> votes used to calculate the Wilson score interval
`down_votes`
`net_votes` -> up vote minus down votes
There are other tables like one that links user with friends they have, it is called users_friends
`user_id` -> contains id of the user that added the friend
`friend_user_id` -> contains id of the friend in question
With these two tables I am able to get all the pictures posted by the friend of a user using this sql query :
SELECT *
FROM photos
WHERE uploader IN
(
SELECT friend_user_id
FROM users_friends
WHERE user_id = ':user_id'
)
ORDER BY id DESC
I then have two queries to get the link to the next picture and 2 other queries for the previous one. I have two because one is for when you get at the end of the database to go back to the other end and the other one is for all the other queries. And they look something like this (I'm only posting the next button here)
$sql = "SELECT *
FROM photos
WHERE status = 0 AND id < ".$id." AND Uploader IN (SELECT friend_user_id FROM users_friends WHERE user_id = ".$logedInUser['User_ID'].")
ORDER BY id DESC
LIMIT 1
";
$sql2 ="SELECT *
FROM photos
WHERE id = (SELECT MAX(id) FROM photos WHERE status = '0' AND Uploader IN (SELECT friend_user_id FROM users_friends WHERE user_id = ".$logedInUser['User_ID']."))
ORDER BY id DESC
LIMIT 1
";
$result = $db->sql_query($sql);
if (mysql_num_rows($result)==1) {
$row = $db->sql_fetchrow($result);
return "/photo/".$row["id"]."/".urlFriendly($row["Title"])."/".$filter.$sort;
}
else
{
$result = $db->sql_query($sql2);
$row = $db->sql_fetchrow($result);
return "/photo/".$row["id"]."/".urlFriendly($row["Title"])."/".$filter.sort;
}
I feel like there is a lot of stuff that could be simplified, but I don't yet know how to do it.
I also have the Lower bound of Wilson score sql code to implement for the next/previous button, and it is quite a bit sql code to have to write 4 time. Maybe that I can insert the Wilson score in the photos table, which could simplify a lot the sql code.
It would be helpful if you could post the structure of your table - i.e. what columns/types you have and what each row represents. I'll assume that you have a table where each row represents a photo, and that each photo has an ID, filename, and various other columns that help you filter/sort (such as date, favorite, etc.).
If your filtering and sorting preferences are defined by the user, you can then use those in a single SQL query, whereby you get the full set of ordered results. For instance:
$sort = date;
$filter = favorite;
$sql = "SELECT ID, filename, [other vars here]
FROM photos
WHERE " . $filter . " = TRUE
ORDER BY ". $sort . " DESC";
$result = $db->sql_query($sql);
Now, you can use a function such as mysql_fetch_array to step through each row in your result set and populate some kind of data structure with the current, previous, and next photos.