How can I write this SQL query? Displaying friends - php

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.

Related

how to make the link between my 2 sql tables?

I cannot correctly make the link between my 2 tables, I have a table that represents my users and another with appointments but I would like to make the link between the 2 to be able to display the appointments users.
My reservation table looks like this :
[tablebooking]
My user table looks like this :
[tableusers]
What I Tried :
[test]
If your appointment functionality is one to one relation like one appointment will have only one member then you can use below query(query followed fields from your screenshots)
SELECT
M.*, B.*
FROM
members AS M
INNER JOIN bookings AS B ON B.userid = M.userid
OR
if you want to have more than one members in one appointment, you need to have tables as below
[YOUR_USERS_TABLE_NAME] => Users list
[YOUR_BOOKINGS_TABLE_NAME] => List of appointments created
[YOUR_BOOKING_MEMBERS_TABLE_NAME] => It should have list of appointment id and members id(one(appointment) to many(users) relation)
and query will be like below
SELECT
B.*, U.*
FROM
[YOUR_BOOKINGS_TABLE_NAME] AS B
INNER JOIN [YOUR_BOOKING_MEMBERS_TABLE_NAME] AS M ON M.bookingid = B.id
INNER JOIN [YOUR_USERS_TABLE_NAME] AS U on M.userid = U.id
GROUP BY B.id, U.id
Hope my answer will help you.
Please add user_id in your bookings table and then run below query in your phpmyadmin.
select * from bookings as b INNER JOIN users as u ON u.id = b.user_id
Thanks.
You probably must use an external table to connect this tables.
EX:
foo{
id: primary,
idTableUser: external key,
idTableBooking: external key
}

Mysql request SELECT with LEFT JOIN

I am a beginner in MySQL, I had some courses in mysql that are now finished, I have a homework , provided by our teacher, to make for my training but I block to retrieve data from the base for a social network site. I understand the basis of JOIN but I still have trouble understanding the logic of LEFT JOIN OR OTHER type INNER JOIN ...
Here is my problem, I have a database with 2 tables,
member(id_member*, login, photo)
friend(id_member_request*, id_member_accept*, accept, date_acceptation)
The accept field of the friend table is a field that allows me to validate if they have friends by setting the value to 1 instead of 0.
The fields id_member_request and id_member_accept agree to the id_member of the member table.
I want to retrieve the login and the picture of the members who are friends, to be able to display them then.
I tested several queries:
SELECT m.login
, m.photo
FROM friend AS a
LEFT
JOIN member AS m
ON m.id_member = a.id_member_accept
LEFT
JOIN member AS m1
ON m1.id_member = a.id_member_request
WHERE accept = 1;
The query works but does not show all friendly members and even several times some people.
In RIGHT JOIN The result is NULL.
In INNER JOIN no result.
Thanks in advance because I blocked for several hours and I confess to lose myself a little. ;-)
Formatting the statement will help you :)
Okay, so you are joining the same column on both m and m1.
The following will bring back the data, but you have to pass in id_member_request..
DECLARE INT #MEMBERID = 2; --Example ID
SELECT m.login, m.photo
FROM friend AS a
LEFT JOIN member AS m ON m.id_member = a.id_member_accept
WHERE a.id_member_request = #MEMBERID
AND a.accept = 1;
This is bring back the m.login, m.photo for all of the friends for the Member with the ID #MEMBERID;
I think you want the friends of person who logged in. means for particular Member_Id here is query that will help you
select * from friend a
inner join member b on (a.id_member_request=b.id_member or a.id_member_accept=b.id_member) and b.id_member=1
where accept=1
where 1 is a member id whose friends will be displayed
You could re-write your query as in the below example
SELECT `m`.`id_member` AS `memberID`,
`m`.`login` AS `memberLoginName`,
`m`.`photo` AS `memberPhoto`,
`m1`.`id_member` AS `friendID`,
`m1`.`login` AS `friendLoginName`,
`m1`.`photo` AS `friendPhoto`,
`a`.`accept_date` AS `acceptDate`
FROM `friends` AS `a`
INNER JOIN `member` AS `m` ON `a`.`id_member_request` = `m`.`id_member`
INNER JOIN `member` AS `m1` ON `a`.`id_member_accept` = `m1`.`id_member`
WHERE `a`.`accept`=1
ORDER BY `a`.`id_member_request`,`a`.`id_member_accept` ASC
View this example in SQL fiddle
Thanks a lot for your help ;-)
I've tried all your answers and with a little change, this one works fine even in INNER, LEFT, RIGHT JOIN...
SELECT login,photo
FROM friend AS a
INNER JOIN member AS m ON ( a.id_member_request = m.id_member
OR a.id_member_accept = m.id_member )
WHERE m.id_member !=$id_member
AND a.accept=1;

facebook type wall post script

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.

Mysql Query Relations M-M Table

I'm having a small problem making a query in MySQL.
I have the following tables:
member;
group;
member_has_group (this one has the columns id_group referes to the group id and id_member referes to member id)
I'm trying to make a query that gives me the members from a selected group. Can you help me?
I'm not familiar with join tables, but for the search i made i think thats probably one of the solutions.
Thanks in advance.
Elkas
If you know the group id
select member.* from member m
inner join member_has_group mg on m.id = mg.id_member
where mg.id_group = [x]
If you only know the group name
select member.* from member m
inner join member_has_group mg on m.id = mg.id_member
inner join group g on g.id = mg.id_group
where g.name = 'group name'
This is trival in SQL :
SELECT m.id_member, m.name
FROM member AS m
INNER JOIN member_has_group AS h ON (m.id_member=h.id_member)
WHERE (h.id_group=#my_id_group)
#my_id_group is the group id you have to give.
Yep, you need a join here.
SELECT *
FROM `member`
JOIN `group` ON member.id = group.id
JOIN `member_has_group` ON group.id = member_has_group.id
Depending on the information in your tables, you may not need the third table at all.You only need a connector table with you have a "many to many" relationship between then.
(Ignore the rest if you already know
about database normalization)
For example, if you had two tables, Authors and Books. Authors would contain fields such as Name, Publisher, Birthday, whatever is a property of the "author". Books would contain relevant "book" information. This is a "one-to-many" relationship. An author may be linked (via a field such as author_id) to several books, but a book can only have one author. You would not need a third table here.
Building on that, say you had a third table for "Character Names". This would be a list of main character names used in any of the books in the "Books" table. One of the characters happens to be named John Steele. John has a whole series of books written about him. In the Books table, several of the books may list John Steele as a character. While in the characters table, John Steele could be listed in several books. This is "many-to-many". You need a third table here. It would only have two fields. A book_id and character_id, one entry for each book that John Steele appears in.
MySql Manual on DB Normalization

Join SQL tables

Suppose that in table "ab" I have the names of the students that get along from class "a" and class "b", identically I have table "ac" and "bc". What SQL query should I use in order to get all the combinations possible of students who can form groups (i.e. "get along together")? And how can i extend this to n classes?
For example: John from class a gets along with Jen from class b and Steff from class c, and Jen and Steff get along. Therefore John, Jen and Steff can form a group).
For this I would create two tables, a student table (id, name, class) and a relationship table (student1, student2). You might also want to add a class table for the time, location etc of the class.
A friendship would have two relationships (2,3) and (3,2) to describe it as two way. One way might be a follower or fan of another student.
This will scale up to a lot more than 3 classes.
Then you can use multiple joins to get friends of friends and so on to an arbitrary depth.
Here is a query to get friends of friends (fof):
SELECT fof_details.*
FROM relationships r
INNER JOIN relationships fof
ON r.student2 = fof.student1
INNER JOIN student fof_details
ON fof_details.id = fof.student2
WHERE r.student1 = '12';
There are also database engines made specifically for doing graph modeling like this.
http://openquery.com/blog/graph-engine-mkii
This query should return all students who can be in one group with John.
WITH ABC AS (SELECT AB.A, AB.B, AC.C FROM (SELECT * FROM AB
INNER JOIN BC
ON AB.B=BC.B)
INNER JOIN AC
ON (AC.C=BC.C AND AB.A=AC.A))
SELECT STUDENT FROM (
SELECT AB.B STUDENT FROM ABC WHERE AB.A='John'
UNION
SELECT AC.C STUDENT FROM ABC WHERE AB.A='John')
GROUP BY STUDENT
PS.: Written fast without any syntax check, hope you'll be able to bring this to work :)
The initial query can be satisfied by the code
select ab.a, ab.b, ac.c
from
ab inner join
bc on ab.b = bc.b inner join
ac on ac.a = ab.a and bc.c = ac.c
Stepping up to n classes will get progressively more complex as n=4 would be the same query with the additional three joins
inner join ad on ab.a = ad.a
inner join bd on bd.b = ab.b and ad.d = bd.d
inner join cd on cd.c = ac.c and ad.d = cd.d
2 classes requires 1 table and no joins,
3 classes requires 3 tables and 2 joins,
4 classes requires 6 tables and 5 joins
So we can see it getting progressively more complex as we proceed
First you don't want to have a table for each class. You are capturing the same type of information in multiple tables and this is generally considered a bad practice. You want to "normalize" your data so that the same data exists in one place.
Second, name your tables appropriately so that you understand what you are actually trying to build. Maybe you are generalizing to mask what your intentions for the actual implementations are by using "ab" in the question, but if you are doing this in your actual code it will hurt you in the long run.
It appears you need a people table with names and a friends table where you track who is friends with who:
create table people ( id int, name char(128) );
create table friends ( id int, person_id int, friend_id int );
Then you just need to have the query to get the groups:
SELECT person.* FROM friends
INNER JOIN friends grp
ON friends.friend_id = grp.person_id
INNER JOIN people person
ON person.id = grp.friend_id
WHERE friends.person_id = 42;

Categories