help me in this query - php

i am trying to develop a site where users can become friends of each other and can see their posts after the date the became friends........i have already posted this question about 5-7 days but could not find any solution........!!
so...
i have two tables..........
posts and friends
and my query is
$sql = mysql_query("
SELECT *
FROM posts p
JOIN friends f
ON p.currentuserid = f.friendid
AND p.time >= f.friend_since
OR s.currentuserid=$myid
WHERE f.myid=$thisid
ORDER BY p.postid DESC LIMIT 20");
where $myid is currentuserid and p.currentuserid is the name of cell in poss table and friendid is in friends table.
this query is working all the way right but problem is that in this query if current user post any thing it displays two times i.e
my new post
mynew post
but in database it is single entry.....!! but current user can see their friends posts for single time
how can i solve this problem

this query is working all the way right but problem is that in this query if current user post any thing it displays two times
Use:
SELECT DISTINCT *
FROM posts p
JOIN friends f ON p.currentuserid = f.friendid
AND p.time >= f.friend_since
OR s.currentuserid=$myid
WHERE f.myid=$thisid
ORDER BY p.postid DESC
LIMIT 20
I added the DISTINCT keyword in order to remove duplicates. Usually I'd use a GROUP BY instead, but you didn't supply the columns.

Related

Getting two different results by one SQL query

First I am new to SQL and PHP.
I have created a simple social networking web app so users can post and follow others to see new posts from them.
At home page a user can first see posts from all users he is followong.
but what i want is to make the user see some other random popular posts that will be ordered by Likes.
here what i have done to get posts from users i follow:
SELECT * FROM posts WHERE author_id in
(SELECT followedID FROM follows WHERE
followerID=:myID)
ORDER BY id DESC LIMIT 10
Now let's say you are following only 1 person. and that person has only one post. here you will see no more than a post!
That's why i want to show more posts when a user has already seen all posts.
i want some easy way to get other posts when the above query has done getting some specific posts.
This is the next query i'd like to execute.
SELECT * FROM posts ORDER BY post_likes DESC LIMIT 10
I wouldn't recommend union, because it incurs overhead for removing duplicates.
Instead, you can use a LEFT JOIN:
SELECT p.*
FROM posts p LEFT JOIN
follows f
ON p.author_id = f.follows_id AND
f.followerID = :myID
ORDER BY (f.follows_id IS NOT NULL) DESC,
(CASE WHEN f.follows_id IS NOT NULL THEN p.id END),
p.post_likes DESC
LIMIT 10;
The ORDER BY puts the followed posts first. The other two clauses order each of the groups by the criteria you want.
You may use UNION to do what you want
(SELECT * FROM posts WHERE author_id in
(SELECT followedID FROM follows WHERE
followerID=:myID)
ORDER BY id DESC limit 0,10)
union
(SELECT * FROM posts ORDER BY post_likes DESC limit 0,10)
LIMIT 0, 10
UNION will automatically append the 2nd query result to the 1st query result, and then show only the number of records specified by the LIMIT clause
Please note that union works only if the queries are of the same structure (which in this case is positive)
Please note that the use of parenthesis is mandatory if you use order by or limit or both
I have used 3 limit clauses (one for each query , and one for the final result of union) AND Both queries have ORDER BY clause. This is to make sure that the records extracted are what you want. (to show the followed posts first, and both are ordered properly)

Add up column using while not breaking other code

My connect to my database works fine so I will include just the code. What I am trying to do is create a sum of the total hours spent on a specific project. The code I have right now displays the comments all the comments from the last day the project was updated:
$query = "SELECT id, date,(select username from users where id = u.user_id) as user, (select description from requests where id = u.request_id) as request, notes, hours from updates u where u.request_id=$rid and date(date) = (select max(date(date)) from updates where request_id = $rid) order by (select description from requests where id = u.request_id) asc";
This is how it is displayed on the web page:
Click to see image of what is displayed on web page
The "test" code that I have that will add the total hours:
$query = "SELECT id, date,(select username from users where id = u.user_id) as user, (select description from requests where id = u.request_id) as request, notes, SUM(hours) as clienthours, hours from updates u where u.request_id=$rid and date(date) = (select max(date(date)) from updates where request_id = $rid) order by (select description from requests where id = u.request_id) asc
This is how it is display on the web page. Notice that all the other comments are gone except the first one of the day.
Click to see image of what is display on web page
I tried adjusting the order of the query but it will send me errors and break the code. I haven't been able to find a solution and would appreciate any help I can get. I am not very advanced when it comes to PHP so my methods are odd and I am building off of someone else code. Any advice will help!
Thank you.
I'd suggest that the main issue with your second script is that you are trying to SUM a column which is returning one row, in SQL you can only return a SUM() when it is the only column in your SELECT.
The below should get around this and also will be more efficient for you by using joins (I've made the assumption that updates.request_id is the unique primary key)
SELECT up.id, up.date, us.username, description, notes,
(SELECT SUM(Hours) FROM updates z WHERE z.request_id = up.request_id)
FROM updates up
INNER JOIN requests r ON u.request_id = r.id
INNER JOIN users us ON up.user_id = us.id
WHERE up.request_id = $rid AND
up.date = (SELECT MAX(date) FROM updates WHERE request_id = $rid)
ORDER BY r.description ASC;

Mysqli - How to build the Query?

I try to request my Database so i will get like in Facebook a News Feed (newest Posts) on the Home Site.
I have a Table with Friends- userid1 - userid2- accepted
So if accepted == 1 they are Friends ...
I already tried to Request first the Friends and then get the Posts... Wrong way cause at least they shown it in the Right way with ordered by timestamp...
But in blocks for each friend...
not ordered only by Timestamp ...
SELECT * FROM friends
WHERE user1='$ownid' or user2='$ownid'
AND accepted='1'
My Post table:
Userid- from_user_id- timestamp- text
SELECT * FROM posts
WHERE from_user='$friendsuserid'
ORDER BY RAND() , timestamp desc
So my Question,
What is the exact query to get fast all post from my Friends and order them by timestamp ?
Means-> Check whos friedn-> getPosts -> order by Timestamp
and all this in 1 Query.... ?
Thanks for every Answer.
Try this:
SELECT * FROM posts p INNER JOIN friends f ON
((p.from_user=f.user1 OR p.from_user=f.user2) AND (f.user1='$ownid' OR f.user2='$ownid') AND f.accepted)
WHERE p.from_user!='$ownid' ORDER BY p.posted_time DESC

One record 27 times

I have a big problem with MySQL. I want to write script like facebook newsfeed.
My query return me 27 the same records. I don't know why.
How it works?
Script displaying posts written by me, my friends or my profile.
My tables:
users:
id, firstname, lastname
friends:
friend1, friend2, status, date
wall:
update_id, author, to_profile, content, date, photos
My query:
SELECT wall.update_id, wall.author, wall.to_profile, wall.content, wall.date, wall.photos, users.*, friends.sender_id, friends.friend_id, friends.status
FROM
wall
INNER JOIN friends ON
wall.author = friends.sender1
AND friends.friend2 = '".$_SESSION['id']."'
AND friends.status = '1' OR wall.author = '".$_SESSION['id']."'
OR wall.to_profile = '".$_SESSION['id']."'
INNER JOIN users ON users.id = wall.author
ORDER BY wall.date DESC
I also want to display post written by pages which I liked.
I created tables:
pages:
page_id, page_name
page_likes:
page_id, user_id, date
and *pages_wall:**
like_id, page_id, user_id, date
How to connect this to my query? And (the most important) how to repair my query?
Thanks in advance,
Matthew
That's a lot of joining going on. Try using your JOINs just to connect the tables, and then use WHERE to cut down the results. Because as it stands, those ORs aren't working like you probably think they are, they need some () around them.
I think you need some structural changes to this database for it to work well in the future. I'd add an ID field to friends, even if just on the admin side, you're going to want to manage those records.
Also, you shouldn't be querying user.* in this query. It seems like you want to pull out every user setting... for every single wall post. This will get rid of "INNER JOIN users ON users.id = wall.author " at the end which will help. Get that information in it's on query prior to calling this wall display.
SELECT *
FROM users
WHERE users.id = wall.author

In PHP + MySQL, How do I join many tables with conditions

I'm trying to get the users full activity throughout the website.
I need to Join many tables throughout the database, with that condition that it is one user.
What I currently have written is:
SELECT * FROM
comments AS c
JOIN rphotos AS r
ON c.userID = r.userID
AND c.userID = '$defineUserID';
But What it is returning is everything about the user, but it repeats rows.
For instance, for one user he has 6 photos and 5 comments
So I expect the join to return 11 rows.
Instead it returns 30 results like so:
PhotoID = 1;
CommentID = 1;
PhotoID = 1;
CommentID = 2;
PhotoID = 1;
CommentID = 3;
and so on...
What am i doing wrong?
What I'm trying to achieve (example)
If you're a facebook user, every profile has a 'wall' which states the user's activity on the website in chronological order. I'm trying to make something similar.
What am i doing wrong?
you are using one complex query when you could use two simple ones.
You should do it as follows:
SELECT * FROM user AS u
LEFT JOIN rphotos AS r ON u.userId = r.userID
LEFT JOIN comments AS c ON u.userId = c.userID
WHERE u.userId = '$defineUserID'
Updated to fix silly mistakes
What this does is select all relevant users from the user table (1 in this case) then join in the other tables where necessary and shouldnt repeat rows.
The query also makes more sense when you think about it logically.
That you get 30 results if a specific user has 6 photos and 5 comments is quite normal, since you're just fetching the cartesian product of all photos and comments based on user ID. The table structure could shed some light onto possible solutions, but if the comments are related to the photos and you want to fetch all photos and the comments a specific user posted you might use something like :
SELECT * FROM rphotos p
LEFT JOIN comments c on c.photoID = p.photoID
WHERE p.userID = '$defineUserID' OR c.userID = '$defineUserID';
Personally I would split this into 2 queries and display the results separately because mixing them doesn't make any sense to me, ie. use
SELECT * FROM rphotos p
WHERE p.userID = '$defineUserID';
and
SELECT * FROM comments c
WHERE c.userID = '$defineUserID';
edit based on comment
If the ID fields are of the same type you could use something like
select actionID, relatedID, creationDate from
(
select 1 as actionID, photoID as relatedID, creationDate from rphotos
where userID = '$defineUserID'
union
select 2 as actionID, commentID as relatedID, creationDate from comments
where userID = '$defineUserID'
) actions
order by creationDate desc;
The actionID will be 1 for a photo, 2 for a comment and using the relatedID field you could lookup the linked data (if you need it, otherwise you could just drop it from the query).
BTW You probably want to filter the results further (ie. based on date) to prevent joining lots of rows in the union that you won't display...

Categories