One record 27 times - php

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

Related

Getting user id from on table and counting them in another table

I have to make a scores page for a game and one thing it has to display is the number of times the current user has played the game. Basically what i need to select ID and username from one table, link them together and count the corresponding user IDs from another table.
These are the tables I was given: Users --> ID, USERNAME and Times_Played --> ID, USER_ID
Thanks in advance
You want to query something like this:
SELECT Users.USERNAME, Times_Played.User_ID
FROM Users
INNER JOIN Times_Played
ON Users.ID=Times_Played.ID;
EDIT
After re-reading the question and seeing the need to count the times played you could do this via PHP or via your SQL Query. Via PHP:
$result = mysqli_query(
"SELECT Users.USERNAME, Times_Played.User_ID
FROM Users
INNER JOIN Times_Played
ON Users.ID=Times_Played.ID"
);
$timesPlayed = mysqli_num_rows($result);
If it has to be done via the query, Anish has the correct solution.
I hope that helps.
Try this
select count(*) as Times_Played,Users.USERNAME,Users.ID
from Users
inner join Times_Played
on Users.ID = Times_Played.USER_ID

Inner, outer or full join on three tables in MySQL database on linux with apache

I want to have some help creating my query to get information from three different tables sharing information in common.
My first table is:
auctions
id title description user_id(who posted it)
My second table is:
bids
id user_id bid auction_id owner_id
My third table is:
users
id username X XX XXX XXXX
...and my SQL is as follows however it's not returning any results:
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title FROM auction_bids, auctions
WHERE auctions.user_id=".$_SESSION['userid']."
INNER JOIN users ON auction_bids.user_id = users.id
WHERE auction_bids.owner_id = ".$_SESSION['userid']."
What I need is to capture the auction's title, username who bidded on the auction and the bid. the auction has to have a bid and posted by the user who owns the $_SESSION['userid'].
Any help is appreciated.
You have two different 'where' statements, which may just need combining;
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title FROM auction_bids, auctions
INNER JOIN users ON auction_bids.user_id = users.id
WHERE auction_bids.owner_id = ".$_SESSION['userid']." AND auctions.user_id=".$_SESSION['userid']."
However, I'm not sure this is really what you want, as it will return only records where the specific user both 'owns' the item AND has bidded on it (both based on the userid session), rather than displaying all records from different people who have bidded on an item 'owned' by the user.
Something like: ?
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title FROM auction_bids, auctions
INNER JOIN users ON auction_bids.user_id = users.id,
WHERE auction.owner_id = ".$_SESSION['userid']."
Hope this points you in the right direction!
you have 2 where clauses, that is incorrect. I have revised your query based on your requirements.
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title
FROM auction_bids, auctions
INNER JOIN users ON auction_bids.owner_id = users.id
WHERE auction_bids.owner_id = ".$_SESSION['userid']."
AND auctions.user_id=auctions_bids.owner_id

Create news update with comments, how to join tables?

I want to create a news update system, using MySQL and PHP. But i can't get it working, having trouble with the join satement and PHP, so i can display a news update and all the comments attached (and if a valid user is logged in, the person can delete each comment individually). But it is only the JOIN statements i'm having trouble with.
I have these tables and DB schema
news_tbl (news_id, date, user (fk to users_tbl.username), headline, bodytext and picture)
users_tbl (username, email, password, usertype)
comments_tbl (comments_id, name, comment, news_id(fk to news_id))
I have tried with this:
$sqlquery ="SELECT news_tbl.*, users_tbl.*, comments_tbl.*,
COUNT(comments_tbl.comments_id) AS comments_count
FROM news_tbl
LEFT JOIN users_tbl
ON news_tbl.user = users_tbl.username
LEFT JOIN comments_tbl
ON comments_tbl.news_id = news_tbl.news_id
GROUP BY news_tbl.news_id ";
But then i can only display one comment, and i want all the comments, and i want to fecth the ID of each comments, so the user can delete each comment individually. And also i cannot get a news id, if a comment isn't written?
This should get roughly what you want,although you should always share your query and also specify exactly what you pretend to achieve.
Select ut.user_id,nt.news_id,nt.headline, nt.body,ct.comments_id,
ct.comment,count(ct.comments_id) as total
from news_tbl nt
inner join users_tbl ut on ut.user_id=nt.user_id
left join comments_tbl ct on ct.news_id=nt.news_id
group by ut.user_id,nt.news_id
good luck.

$query -> get all 'friends' from user, works but get double times each friend

basicalli, i have a table: friends [id, fromid, toid]
[fromid] and [toid] represents the id of the user, fromid is who asked, and toid who acepted.
I consider two users 'friends' where ther is to items in friends table for each.
example: user 1 is friend of user 2 when i have:
in table friends:[id,1,2],[id,2,1],....
Im trying with this query and as i said in title gets me the 'friens', but two times :S
$sqlQueryCat5 = mysql_query("SELECT friends.*,usuarios.alias AS nombre_amigo FROM friends LEFT JOIN usuarios ON friends.toid=usuarios.id AND friends.fromid='$this->id' ORDER BY id");
I don't know why.. and you?
thank you
It looks like you have another query that you are not showing here.
This query on its own only shows friends once, because friends.fromid='$this->id' means fromid can only be the id asked.
If your table ALWAYS contains [1,2] and [2,1] (both), then you only need to query one side to get the other.
SELECT friends.*,usuarios.alias AS nombre_amigo
FROM usuarios
INNER JOIN friends ON friends.fromid=usuarios.id
WHERE usuarios.id='$this->id'
ORDER BY id
Since your JOIN is not limiting the results of your query (as it is a LEFT JOIN and not an INNER JOIN), I'm guessing you want to move the friend limiter into your WHERE clause, like so:
$sqlQueryCat5 = mysql_query("SELECT friends.*, usuarios.alias AS nombre_amigo "
. "FROM friends "
. "LEFT JOIN usuarios ON friends.toid=usuarios.id "
. "WHERE friends.fromid=$this->id"
. "ORDER BY id");
Edit: looking at your query again, I'm guessing that you don't actually have a reason to use a LEFT JOIN - turn it into a regular JOIN and you could at the very least see a bit better performance.

Friend of a friend in PHP/MySQL?

I have a social network similar to myspace/facebook. In my code you are either a person's friend or not a friend, so I show all actions from people you are friends with (in this post I will refer to actions as bulletin posts alone to make it easier to visualize.
So you every time a person post a bulletin it will show up to any person who is there friend.
In mysql you would get a persons friend list by doing something like this,
SELECT user_id FROM friends WHERE friend_id = 1 (user ID)
I want to know how a site like facebook and some others would show all bulletin post from your friends and from your friends' friends?
If anyone has an idea please show some code like what kind of mysql query?
The answer is that they aren't doing selects on a friend table, they are most likely using a de-normalized news-event table. We implemented a news-feed similar to Facebooks on DoInk.com, here's how we did it:
There is the notion of a "NewsEvent" it has a type, an initiator (a user id) and a target user (also a user id). (You can also have additional column(s) for other properties relevant to the event, or join them in)
When a user posts something on another users wall we generate an event like this:
INSERT INTO events VALUES (wall_post_event, user1, user1)
When viewing user1's profile, you'd select for all events where user1 is either the initiator or the target. That is how you display the profile feed. (You can get fancy and filter out events depending on your privacy model. You may consider doing this in memory for performance reasons)
Example:
SELECT * FROM events WHERE initiator = user1 or target = user1 //to see their profile feed
SELECT * FROM events WHERE initiator IN (your set of friend ids) //to see your newsfeed
When you want to see the newsfeed for all events relative to your friends you might do a query selecting for all events where the initiator is in your set of friends.
Avoid implementations with sub-selects, depending on the complexity, they will not scale.
you do a subquery:
SELECT DISTINCT user_id FROM friends WHERE friend_id IN
(SELECT user_id FROM friends WHERE friend_id = 1)
Test both of these for performance:
SELECT DISTINCT user_id
FROM friends f1
JOIN friends f2 ON f1.friend_id = f2.user_id
WHERE f2.friend_id = 1
and
SELECT DISTINCT user_id
FROM friends
WHERE friend_id IN (SELECT user_id FROM friends WHERE friend_id = 1)
Often they're the same but sometimes they're not.
Make sure friend_id and user_id are indexed.
The simple approach would be to do some kind of simple nested clause. So say you have a table with posts and the posters id, and a friends table, the first layer would be
SELECT post FROM posts JOIN friends
on post.userid = friends.friend_id
WHERE friend.id = 1 (user ID)
then to get a friends of friends
SELECT post FROM posts JOIN
(SELECT DISTINCT friends_2.friend_id FROM friends AS friends_1
JOIN friends as friends_2
on friends_1.friend_id = friends_2.id where friends_1.id = 1)
AS friends
wHERE post.userid = friends.friend_id AND mainid = 1 (user ID)
You can repeat this nesting each time you want to add another layer of friend abstraction. The problem with this approach is that it would take a very long time to execute. For every time you add a layer of friend abstraction you are increasing the complexity by a power of n (where n is the number of rows in your table).
It is more likely that they are saving the viewable friends in a table somewhere, so lets make a new tabled called friends_web
user_id, friend_id, level
when a user friends someone, it adds that new friend into friends_web at a level of 0(since that friend is no people away) then adds that friends friends at a level of 1 (since its 1 friend away). In order to keep the table integrity you would also want to add the inverted record. To clarify if A adds B as a friend and C is a friend of B, the following two records would get added to our new table
A, C, 1
C, A, 1
since now A can see C and C can see A.
now when we want a query we just do
SELECT post FROM posts
JOIN friends_web ON post.user_id = friends_web.friend_id
WHERE friends_web.user_id = user_id AND friends_web.level < 2 (or however deep you want to look)
by doing that you minimized your query complexity when doing post lookups while being able to look more then 1 layer deep into a friend web.
Sorry for the long winded response.
This should pull out all the user's friend's posts.
SELECT * FROM posts WHERE uid IN (SELECT friend_uid FROM friends WHERE uid=1) ORDER BY post_id DESC
This should pull out all posts that are your friend's friend's.
SELECT * FROM posts WHERE uid IN (SELECT friend_uid FROM friends WHERE uid IN (SELECT friend_uid FROM friends WHERE uid=1)) ORDER BY post_id DESC

Categories