facebook type wall post script - php

I have two mysql tables members_tbl and post_tbl
members_tbl:
id|userName |fname |lname |friendArray
post_tbl:
postId| memId | thePost |postDate
now, I'm trying to display post from user id and from his friendArray.
please let me know how to do it (still new to php)

Since MySQL lacks an explode function, you either need to create a relation table and use joins, or use multiple queries with php processing inbetween. I strongly recommend the relational approach as it conforms to database standards (normalization) much more than the alternative and is easier to implement.
You need a third table, which describes the relation between two friends, I.E.
friends_tbl
user1_id | user2_id
With a primary key on user1_id and user2_id (thereby preventing duplicates). For every friend relationship, I.E. user 1 is friends with user 2, there is one row in this table. You can then get the listing you want with the following query.
SELECT p.*, u.*
FROM posts_tbl p
INNER JOIN members_tbl u
ON u.id = p.memId
WHERE u.id IN (
SELECT user2_id AS id
FROM friends_tbl
INNER JOIN members_tbl
ON (user1_id = id)
WHERE members_tbl.id = $id
UNION
SELECT user1_id AS id
FROM friends_tbl
INNER JOIN members_tbl
ON (user2_id = id)
WHERE members_tbl.id = $id
)
ORDER BY p.postDate
SQLFiddle of the above.

create a different table for your friend-relations and then join this table in your SQL.

Related

How can I write this SQL query? Displaying friends

I am developing a friend system, which handles friend requests and friendships.
I have a table named Member where I keep information about each member including their id, first and last name
and another table named Friendships where I keep track of the id of the first friend Friend1 and the second Friend2 and the date of the friendship formation.(Note: each request is recorded twice in my database; ex 1 -> 2 and 2->1 )
I am trying to write a query to display the first and last name of the friends of the current user. I know I have to INNER JOIN both tables, but I am not sure ON what exactly.
Assuming the friend table and members table have same ID columns,
SELECT m.first, m.second
FROM m.member INNER JOIN f.friendships
ON f.id = m.id;
Could be somthings like this
select a.firstname, b.lastname from Member a
inner join Friendships b on (b.friend1_id = a.id )
and a.id = 'current_user_id'
On the foreign keys (I guess Members.Id=Friendships.Friend1) but it really depends on the semantics you are implementing with those duplicate (bidirectional?) friendship relations.

Best way to store "Other" data into MySQL database

I have a form with radio buttons which stores the value (which is the ID) in my MySQL database along with the necessary information from the user.
INSERT INTO table (user_id, name, address, prefer_id) VALUES ('', ?, ?, ?);
So when I try to fetch the data, I use LEFT JOIN, to get the necessary description from table2:
SELECT a.name, a.address, b.prefer_desc FROM table a
LEFT JOIN table2 b ON a.prefer_id = b.prefer_id
WHERE a.user_id = ?
But I have created an other option, in case the option the user prefers is not in the list. A textbox will appear when the user selects Other in the list of radio buttons so they can type-in freely their preferred data. Check this fiddle to see an example.
The first logic that I've thinked of is to create a separate table which stores the typed-in data of the user.
other_tb:
other_id | user_id | typed_in |
----------+---------+----------+
1 | 1 | cake |
2 | 3 | pizza |
So when I fetch the data, I use php's if() condition if the prefer_id is 4 (or other), and if it does, I will use another SELECT query to get the other data in other_tb table.
SELECT typed_in FROM other_tb WHERE user_id = ?
Is there a way to do all of this in a single query?
OR
Is this the best option, or is there a right or better way in this kind of situation?
try this
SELECT
a.name,
a.address,
IF(a.prefer_id=4,(SELECT typed_in FROM other_tb WHERE user_id = a.user_id),b.prefer_desc) as prefer_desc
FROM table a
LEFT JOIN table2 b
ON a.prefer_id = b.prefer_id
WHERE a.user_id = ?
If you are using the second table as you described, and you want to keep the same format of the output and assuming the records in other_tb are unique for each user_id, you could use something like this:
SELECT a.name, a.address,
CASE
WHERE a.prefer_id = 4 THEN c.typed_in
ELSE b.prefer_desc
END CASE AS prefer_desc
FROM table a
LEFT JOIN table2 b ON a.prefer_id = b.prefer_id
LEFT JOIN other_tb c ON a.user_id = c.user_id
WHERE a.user_id = ?
I think this can also be written as:
SELECT a.name, a.address,
CASE a.prefer_id
WHERE 4 THEN c.typed_in
ELSE b.prefer_desc
END CASE AS prefer_desc
FROM table a
LEFT JOIN table2 b ON a.prefer_id = b.prefer_id
LEFT JOIN other_tb c ON a.user_id = c.user_id
WHERE a.user_id = ?
There are two approaches that I was able to practice depending on the situation:
Allow users to add more options so that their answer is still indexed to table2. So when fetching data, you may still use LEFT JOIN to get the user's preferred option without any other condition. But this method will allow users to see the options that was added by other users.
If the options are "fixed" and only the administrator is allowed to add options to table2, have another column to table1, which stores the other answer of the user (let say other_option column). This method allows the user to still freely state their option without adding options to table2.
Here is table1:
+---------+------+---------+-----------+--------------+
| user_id | name | address | prefer_id | other_option |
+---------+------+---------+-----------+--------------+
What I do is I put 0 to prefer_id if the user prefers to answer other_option. So your program expects that if the prefer_id is 0, you have an input in other_option.

SQL Optimization WHERE vs JOIN

I am using mysql and this is a query that I quickly wrote, but I feel this can be optimized using JOINS. This is an example btw.
users table:
id user_name first_name last_name email password
1 bobyxl Bob Cox bob#gmail.com pass
player table
id role player_name user_id server_id racial_name
3 0 boby123 1 2 Klingon
1 1 example 2 2 Race
2 0 boby2 1 1 Klingon
SQL
SELECT `player`.`server_id`,`player`.`id`,`player`.`player_name`,`player`.`racial_name`
FROM `player`,`users`
WHERE `users`.`id` = 1
and `users`.`id` = `player`.`user_id`
I know I can use a left join but what are the benefits
SELECT `player`.`server_id`,`player`.`id`,`player`.`player_name`,`player`.`racial_name`
FROM `player`
LEFT JOIN `users`
ON `users`.`id` = `player`.`user_id`
WHERE `users`.`id` = 1
What are the benefits, I get the same results ether way.
Your query has a JOIN in it. It is the same as writing:
SELECT `player`.`server_id`,`player`.`id`,`player`.`player_name`,`player`.`racial_name`
FROM `player`
INNER JOIN `users` ON `users`.`id` = `player`.`user_id`
WHERE `users`.`id` = 1
The only reason for you to use left join is if you want to get data from player table even when you don't have matches in users table.
LEFT JOIN will get data from the left table even if there's no equal data from the right side table.
I guess at one point, that player table's data will not be equivalent to users table specially if the data on users table has not been inserted into player table.
Your first query might return null on cases that the 2nd table (player) has no equivalent data corresponding to users table.
Also, IMHO, setting up another table for servers is a good idea in terms of complying to the normalization rules in database structure. After all, what details of the server_id is the column on player table pointing to.
The first solution makes a direct product (gets and connects everything with everything) then drops away the bad results. If you have a lot of rows this will be very slow!
The left join gets first the left table then put only the matching rows from the right (or null).
In your example you don't even need join. :)
This'll give you the same result and it'll be good until you just check for user id:
SELECT `player`.`server_id`,`player`.`id`,`player`.`player_name`,`player`.`racial_name`
FROM `player`
WHERE `player`.`user_id` = 1
Another solution if you want more conditions, without join could be something like this:
SELECT * FROM player WHERE player.user_id IN (SELECT id FROM user WHERE ...... )

How to transfer a lot of values beteen tables in a variable or array?

I have two SQL tables. The first one structure is simple.
ID Name
----------
The second one is simple too.
CommentID Comment CreatorID
----------------------------------
I want to show in my site all the comments that correspond with the "ID of user"
The problem is we have here a lot of ID and two different tables.
Something like this:
$1= $bdd->query("SELECT * FROM comments WHERE id_user=220281");
$2=$1->fetch();
But its impossible because id user is not on the comments table.
The most simple way to do this is to join the tables like this:
select
users.name,
comms.commentID,
comms.comment
from
userTable users
join commentTable comms
on users.ID=comms.ownersID
where
users.id=1
This will return the users name in each row of data, but you don't need to use it in the output more than once.
It also sounds like you could use a few pointers on SQL queries. Do yourself a favour and have a read of this article I put together a while back.
SELECT c.*
FROM comments c
INNER JOIN users u ON c.id_creator = u.id_user AND
u.id_user = 220281
A simple join will do the trick like this :
SELECT c.comment, u.user_name FROM
Users u
JOIN
Comments c ON
c.creator_id = u.user_id
WHERE
u.user_id=220281
fiddle:http://sqlfiddle.com/#!6/3b28a/1

Complex Mysql query to combine 3 tables Data?

I have a table in which I store followers, I have another table in which I store friendships
Now I have third table which stores stream data.
Its a social network, there are many reasons so I don't wish to have one table for follower & friendships (Means facebook subscriptions/friends)
Can someone presents a way how should I query streams table to pick activities of both friends & followings ?
Any help would be really appreciated, thank you
Here is simple Database Scheme, its not really like this but almost!
Okay here is database tables schema please,
Followers table.
Row_ID
User_ID
Following_User_ID
Friends Table
Row_ID
User_ID
Friend_ID
Stream Table
Row_ID
User_ID
Contents_ID
Time
Type
What are you looking for is probably best done as two distinct results sets... or a union of the two.
Select "friend" as src, author, post from friends f inner join streams s on s.author = f.id
union
Select "follower" as src, author, post from followers f inner join streams s on s.author = f.id
This is just some pseudo coding but it should give you an idea of how to proceed. Without knowing your database schema, this is the best I can offer.
Edit:
This might be what your looking for then
select user_id, contents_id, time from (
select user_id, contents_id, time
from followers f inner join stream s on s.user_id = f.user_id and f.user_id = "username"
union
select user_id, contents_id, time
from friends f inner join stream s on s.user_id = f.user_id and f.user_id = "username"
) order by time desc
This will return the data in time order, descending.

Categories