I'm totally lost here and not know how to get this to work and hope any can help me here. I have several tables: default_users, default_profiles, default_status, default_comment and latest default_friend. Here is the SQL for those tables: http://pastebin.com/PxGZ8QYz with some values for testing purpose. So how this should work: a user can have 0:n friend so I insert new records in default_friend table depending on which part start the relation. Suppose I'm user with ID=1 (admin) and want to invite user with ID=2 (demo) then in the default_friend table I insert a record where friend_id = 2 and user_id = 1. Now each time I create a new user I insert data in default_users and default_profiles tables. Also each user can have 0:n status and also each status can have 0:m comment. Then I need to get, if is possible in one SQL query just, all the status and comment from me (ID=1) and also the same for each friend of mine(ID=2 by now could be more than that). I create this query:
SELECT DISTINCT
u.id,
p.display_name,
p.first_name,
p.last_name,
s.status_id,
s.message,
s.created_at AS sdate,
(SELECT friend_id FROM default_friend f WHERE f.friend_id = 1 ) AS f_friend_id,
(SELECT user_id FROM default_friend f WHERE f.user_id = 1 ) AS f_user_id
FROM default_users u
LEFT JOIN default_profiles p
ON (
u.id = p.user_id OR f_friend_id = p.user_id
)
LEFT JOIN default_status s
ON (
u.id = s.user_id OR f_friend_id = s.user_id
)
WHERE u.id = 1
LIMIT 0, 8
But this wont work because user_id = 1 could have 0:m friends.
Also tried this too:
SELECT DISTINCT
u.id,
p.display_name,
p.first_name,
p.last_name,
s.status_id,
s.message,
s.created_at AS sdate,
f.friend_id,
f.user_id
FROM default_users u
LEFT JOIN default_profiles p
ON(
u.id = p.user_id
)
LEFT JOIN default_status s
ON(
u.id = s.user_id
)
RIGHT JOIN default_friend f
ON (
(f.friend_id = 1 OR f.user_id = 1) AND f.approved = 1
)
WHERE u.id = 1
LIMIT 0, 8
But this only give status from me and not from my friends as I want. This is the result of the second query:
[0] => stdClass Object
(
[id] => 1
[display_name] => Reynier Perez Mira
[first_name] => Reynier
[last_name] => Perez Mira
[status_id] => 1
[message] => dasdasdasdasdasd
[sdate] => 2012-08-13 15:15:37
[friend_id] => 2
[user_id] => 1
)
[1] => stdClass Object
(
[id] => 1
[display_name] => Reynier Perez Mira
[first_name] => Reynier
[last_name] => Perez Mira
[status_id] => 3
[message] => dasdsad344hbvnbnhjhgjhjghjhj
[sdate] => 2012-08-13 17:24:53
[friend_id] => 2
[user_id] => 1
)
EDIT: Here is a better approach/result but I get duplicates rows:
SELECT DISTINCT
u.id,
p.display_name,
p.first_name,
p.last_name,
s.status_id,
s.message,
s.created_at AS sdate,
f.friend_id,
f.user_id
FROM default_users u
LEFT JOIN default_friend f
ON (
(f.friend_id = 1 OR f.user_id = 1)
AND
f.approved = 1
)
LEFT JOIN default_status s
ON(
u.id = s.user_id
OR
f.friend_id = s.user_id
)
LEFT JOIN default_profiles p
ON(
s.user_id = p.user_id)
WHERE u.id = 1
LIMIT 0, 8
And here are the results for this one:
[0] => stdClass Object ( [id] => 1 [display_name] => Reynier Perez Mira [first_name] => Reynier [last_name] => Perez Mira [status_id] => 1 [message] => dasdasdasdasdasd [sdate] => 2012-08-13 15:15:37 [friend_id] => 2 [user_id] => 1 )
[1] => stdClass Object
(
[id] => 1
[display_name] => Demo
[first_name] => Demo
[last_name] => Demo
[status_id] => 2
[message] => dasdasdasdasdasd
[sdate] => 2012-08-13 15:16:03
[friend_id] => 2
[user_id] => 1
)
[2] => stdClass Object
(
[id] => 1
[display_name] => Reynier Perez Mira
[first_name] => Reynier
[last_name] => Perez Mira
[status_id] => 3
[message] => dasdsad344hbvnbnhjhgjhjghjhj
[sdate] => 2012-08-13 17:24:53
[friend_id] => 2
[user_id] => 1
)
[3] => stdClass Object
(
[id] => 1
[display_name] => Reynier Perez Mira
[first_name] => Reynier
[last_name] => Perez Mira
[status_id] => 1
[message] => dasdasdasdasdasd
[sdate] => 2012-08-13 15:15:37
[friend_id] => 1
[user_id] => 3
)
[4] => stdClass Object
(
[id] => 1
[display_name] => Reynier Perez Mira
[first_name] => Reynier
[last_name] => Perez Mira
[status_id] => 3
[message] => dasdsad344hbvnbnhjhgjhjghjhj
[sdate] => 2012-08-13 17:24:53
[friend_id] => 1
[user_id] => 3
)
Nota: I added one more field to users table and friend and status to test this latest
EDIT 2: Ok, finally, tough, I found the solution, here it's:
SELECT DISTINCT
u.id,
p.display_name,
p.first_name,
p.last_name,
s.status_id,
s.message,
s.created_at AS sdate
FROM default_users u
LEFT JOIN default_friend f
ON(
(f.friend_id = 1 OR f.user_id = 1)
AND
f.approved = 1
)
LEFT JOIN default_status s
ON(
u.id = s.user_id OR f.friend_id = s.user_id OR f.user_id = s.user_id
)
LEFT JOIN default_profiles p
ON(
s.user_id = p.user_id
)
WHERE u.id = 1
LIMIT 0, 8
Which seems to be correct, by now, because didn't get duplicates and gets exactly what I'm looking for as can see below:
[0] => stdClass Object
(
[id] => 1
[display_name] => Reynier Perez Mira
[first_name] => Reynier
[last_name] => Perez Mira
[status_id] => 1
[message] => dasdasdasdasdasd
[sdate] => 2012-08-13 15:15:37
)
[1] => stdClass Object
(
[id] => 1
[display_name] => Demo
[first_name] => Demo
[last_name] => Demo
[status_id] => 2
[message] => dasdasdasdasdasd
[sdate] => 2012-08-13 15:16:03
)
[2] => stdClass Object
(
[id] => 1
[display_name] => Reynier Perez Mira
[first_name] => Reynier
[last_name] => Perez Mira
[status_id] => 3
[message] => dasdsad344hbvnbnhjhgjhjghjhj
[sdate] => 2012-08-13 17:24:53
)
[3] => stdClass Object
(
[id] => 1
[display_name] => User 1
[first_name] => User
[last_name] => User
[status_id] => 4
[message] => dasdsad344hbvnbnhjhgjhjghjhjsdfsdfsdfsdfdsfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdf
[sdate] => 2012-08-13 17:24:53
)
But now I've another problem getting COUNT(*) as num_rows for that query to works because it returns 6 when should be 4 or I'm wrong?
PS: I must say that all tables will have 10 000 or more records so performance is required.
Cheers and thanks in advance