MySQL JOIN 3 tables search by WHERE on ID from 1 - mysql

I seem to be struggling grasping the concept of joining 3 tables on one ID.
USER Table
|id |
|:----:|
|1 |
|2 |
POST table
|id |userid | content|
|:----:|:----:|:----:|
|1 |1 |HELLO |
|2 |1 |THERE |
|3 |2 |WORLD |
friend table
|id | userid | friendid |
|:----:|:------:|:--------:|
| 1 | 1 | 2 |
I want to provide the ID from the USER table, and get ALL the CONTENT from POSTS where the POST.USERID is the FRIEND.USERID and FRIEND.FRIENDID
So USER.ID = '1' would bring back all the POST.CONTENT(in this case).
Really hope you can help, been annoying me for hours.

Following your description, you would not need to join to the user table, you could directly use the friends table, as you have the userid there. But this should give you all posts from userid 5 and his that persons friends.
SELECT post.*
FROM post
INNER JOIN friends ON post.userid = friends.userid OR post.userid = friends.friendid
WHERE friends.userid =1
To not query duplicates use this:
SELECT post.*, users.firstname
FROM post
INNER JOIN users ON users.userid = post.userid
WHERE post.userid = 1
UNION
SELECT post.*, users.firstname
FROM friends
INNER JOIN post ON friends.friendid = post.userid
INNER JOIN users ON users.userid = friends.friendid
WHERE friends.userid = 1

Related

Select a specific row with additional column that its value is from another column in one table

Suppose I have a table named users consist of columns: user_id, user_name, user_created_by.
+------------------+----------------------+-------------------+
| user_id + user_name + user_created_by +
+------------------+----------------------+-------------------+
| 1 | John | 1 |
| 2 | Ann | 1 |
| 3 | Paul | 2 |
| 4 | King | 2 |
| 5 | Dirk | 3 |
+------------------+----------------------+-------------------+
The value of user_created_by is the user_id who created that record. Now, I want to make a query that results one specific row with added column let's say user_created_by_name which is the user_name of the user_id from the user_created_by. Suppose we want to get "Paul"'s record with who (the name) create it (temporary new column). For ease of understanding this is my expected result:
+----------+--------------+-------------------+------------------------+
| user_id | user_name | user_created_by | user_created_by_name |
+----------+--------------+-------------------+------------------------+
| 3 | Paul | 2 | Ann |
+----------+--------------+-------------------+------------------------+
this is my query using codeigniter:
$query=$this->db->query("SELECT *,
(SELECT user_name FROM users WHERE user_id = user_created_by)
AS "user_created_by_name" FROM users WHERE user_id=3);
But my result are:
+----------+--------------+-------------------+------------------------+
| user_id | user_name | user_created_by | user_created_by_name |
+----------+--------------+-------------------+------------------------+
| 3 | Paul | 2 | NULL |
+----------+--------------+-------------------+------------------------+
You culd use a self join (join the same table two time) using alias for fere to the tables as different sets of data
SELECT a.user_id, a.user_name, a.user_created_by, b.user_name as user_created_by_name
from users a
inner join user b on a.user_created_by = b.user_id
where a.user_id = 3
use self join
select u1.user_id, u1.name as user_name,
u2.user_created_by
,u2.user_name as createdby from users u1
join users u2 on u1.user_id=u2.user_created_by
where u1.user_id=3
You can solve this problem using a JOIN.
$sql = "SELECT users.user_id, users.user_name, user_created_by_name.user_name,
FROM users JOIN users AS user_created_by_name ON users.user_id = user_created_by_name.user_id WHERE users.user_id = 3";
$query=$this->db->query($sql);
If you you have users that were not created by another user use a LEFT JOIN instead:
$sql = "SELECT users.user_id, users.user_name, user_created_by_name.user_name,
FROM users LEFT JOIN users AS user_created_by_name ON users.user_id = users.user_id WHERE user_created_by_name.user_id = 3";
$query=$this->db->query($sql);
This will work:
SELECT a.user_id as User_id,
a.user_name as Name,
b.user_id as Created_by_user_id,
b.user_name as Created_by_name
FROM users AS a
INNER JOIN users AS b
ON a.user_id = b.user_created_by
WHERE a.user_id = 3
It is called a self-join, which is used when combining two records of the same table.

join pivot table in mysql

How to join different tables with pivote table
I have 4 tables like
users
id | name |
-------------
1 | abc |
2 | ccc |
user_profile
id | user_id | email |
-------------------------------
1 | 1 | abc#gmail.com
2 | 2 | ccc#gmail.com
skills
id | skill_name |
--------------------------
1 | java |
2 | php |
user_skills
user_id | skill_id |
---------------------------
1 | 1 |
1 | 2 |
2 | 1 |
The result should be
name | email | skills |
----------------------------------
abc |abc#gmail.com | java, php |
ccc |ccc#gmail.com | java |
I am able to join multiple tables but I have problem joining pivote
I have tried below with query
SELECT users.name,user_profiles.email, group_concat(programs.name)
from users
JOIN user_profiles on user_profiles.user_id = users.id
LEFT JOIN user_skills on user_skills.user_id = users.id
LEFT JOIN skills on user_skills.skill_id = skills.id
GROUP BY users.id
Can anyone help me on this please??Thanks
You need GROUP_CONCAT to generate the CSV list of skills:
SELECT
u.name,
up.email,
GROUP_CONCAT(s.skill_name) AS skills
FROM users u
INNER JOIN user_profile up
ON u.id = up.user_id
LEFT JOIN user_skills us
ON u.id = us.user_id
INNER JOIN skills s
ON us.skill_id = s.id
GROUP BY
u.id, u.name, up.email;
Demo
Note that I group by both the user's id and name, because perhaps two users happen to have the same name. Follow the link below for a running SQLFiddle.
Your query should work. Perhaps the problem is the reference to programs rather than skills:
select u.name, up.email, group_concat(s.name)
from users u join
user_profiles up
on up.user_id = u.id left join
user_skills us
on us.user_id = u.id left join
skills s
on us.skill_id = s.id
group by u.name, up.email;

Mysql query to Join two tables

I am writing a simple chat service. I want to pick out a messages thread between two people only a sender and a recipient using either their usernames or user ids. I have my query below. It has a slight problem, is returning a message twice. How can I fix this?
For example if my sender has the uid '101' and my recipient has the username 'janed', my query is
SELECT * FROM chat LEFT JOIN users ON sender=uid OR receiver=uid WHERE username='janed' OR (sender='101' AND receiver='janed') OR (sender='janed' AND receiver='101') ORDER BY msg_id ASC
Users table
---------------------------------
uid |fname |mname |username |
---------------------------------
101 |John |Doe |jdoe |
---------------------------------
102 |Jane |Doe |janed |
---------------------------------
103 |Ann |Other |aother |
---------------------------------
Chat table
---------------------------------------------
msg_id |sender |receiver |content |
---------------------------------------------
1 |101 |102 | Hello Jane |
---------------------------------------------
2 |102 |101 | Hello John |
---------------------------------------------
3 |103 |101 | Hi John |
---------------------------------------------
Add a GROUP BY clause
SELECT
*
FROM
chat
LEFT JOIN
users ON sender = uid OR receiver = uid
WHERE
username = 'janed'
OR (sender = '101' AND receiver = 'janed')
OR (sender = 'janed' AND receiver = '101')
GROUP BY msg_id
ORDER BY msg_id ASC
SELECT
u.*, c.*
FROM Users u
LEFT JOIN Chat c ON (
c.sender = u.uid OR c.receiver = u.uid
)
WHERE u.uid = 101 OR u.uid = 102 /* and/or other conditions */
GROUP BY c.msg_id
ORDER BY c.msg_id ASC

How to LEFT JOIN three tables with the same column name

I have a three tables that are left join. two of them have uid as user id. Problem is every time query execute it takes the same user id.
Please check the table structure
-------------------------------------
|Users |posts |favorites |
|-----------|-----------|-----------|
|user_id |id |id |
|username |title |uid |
|password |post |post_id |
| |uid | |
| |favorites | |
-------------------------------------
MySQL query
SELECT * FROM favorites
LEFT JOIN users ON users.user_id = favorites.uid
LEFT JOIN posts ON favorites.posts_id = posts.id
WHERE favorites.uid='$id' and posts.active=1
please note that $id is the profile owner (user) id. Any help will be appreciated.
If the table was as follows (I've renamed user_id, post, and favorites columns to clarify their roles as I understand them)
-------------------------------------
|Users |posts |favorites |
|-----------|-----------|-----------|
|id |id |id |
|username |title |uid |
|password |post_text |post_id |
| |uid | |
| |fav_id | |
-------------------------------------
This sql code can be used to get what (I think) you want
SELECT * FROM favorites
LEFT JOIN posts ON favorites.id = posts.fav_id
LEFT JOIN users ON posts.uid = users.id
WHERE favorites.uid='$id' and posts.active=1
This should get all the details of favorite posts from the three tables for the given user id. Hope it works for you.
This query may solve your problem.
SELECT * FROM post p
LEFT JOIN (SELECT * FROM users u LEFT JOIN favorites f ON u.user_id = f.id) as tbl1
WHERE p.id=tbl1.post_id and p.uid = $uid and p.active=1
Hey can you please try this once
SELECT posts.*, favorites.post_id, users.username FROM favorites LEFT JOIN users ON favorites.uid = users.user_id LEFT JOIN posts ON favorites.post_id = posts.id
WHERE users.user_id='$id' and posts.active=1
As there was a typo in the query and i have made few changes to your code

joining and possible sub-queries

I have 3 tables: user, 'user_friends' and 'blog_post'
The schema is similar to the following:
user
id | username
-------------------
1 | jim
-------------------
2 | mary
-------------------
3 | george
-------------------
4 | julie
user_friends
user_id | friend_id
----------------------
1 | 2
----------------------
2 | 3
----------------------
2 | 4
blog_posts
id | title | user_id
------------------------------
1 | test_1 | 1
------------------------------
2 | test_2 | 2
------------------------------
3 | test_3 | 3
------------------------------
4 | test_4 | 4
Ok, so you can see each user has made a blog post. Users have 'friends'. What I'm looking to do, is display each users friends blog posts.
So, If I'd like to see Jims friends posts, it should show mary's post of test_2. If I want to see mary's friends posts, it should show george and julie's posts of test_3 and test_4
Is there an easy way of doing this? Could I use sub-selects?
Many thanks
Yes you can use a sub-selection.
Something like this should work :
SELECT * FROM blog_posts WHERE user_id in
(SELECT friend_id FROM user_friend WHERE user_id=1)
Could be as simple as that (variant with a JOIN):
SELECT bp.*
FROM user_friends uf
JOIN blob_posts bp ON bp.user_id = uf.friend_id
WHERE uf.user_id = my_id
Select *
From blog_posts
Where user_id in
(Select friend_id
From user_friends
where user_id = 1);
the number at the end can be whatever user ID you are looking for.
You can use IN
SELECT * FROM blog_posts WHERE user_id IN (
SELECT friend_id FROM user_friends WHERE user_id = X)
SELECT bp.*
FROM blog_posts bp
INNER JOIN user_friends uf ON bp.user_id = uf.friend_id
INNER JOIN user u ON u.id = uf.user_id
WHERE u.username = "jim"
Try this request:
SELECT bp.title
FROM blog_posts bp
JOIN user_friends uf ON (bp.user_id = uf.friend_id)
WHERE uf.user_id = 1;