joining and possible sub-queries - mysql

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;

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.

Mysql select query - stuck in where condition

I have 2 tables:
Users:
------------------------------
id | name
--------------------------
1 | John
2 | Dane
3 | Foo
4 | Bar
Matches Table:
----------------------------
id | userid1 | userid2
----------------------------
1 | 1 | 3
2 | 2 | 4
Question:
From the matches table with id 1, i want to fetch John and Foo in one query. How can i do that ?
I already have one solution but its dull. That is selecting records from matchs tables and then while looping, trigger queries for getting names. .
Just use a JOIN...
SELECT u1.*, u2.*
FROM Matches m
JOIN Users u1 ON u1.id = m.userid1
JOIN Users u2 ON u2.id = m.userid2
WHERE m.id = [ YOUR DESIRED USER ID (for example: 1) ]
SELECT name from Matches, Users where Matches.id = 1 AND (Users.id = Matches.userid1 OR Users.id = Matches.userid2)
This should work.

How to optimize SQL query more?

First at all i am nood into SQL thing, Now i am working on a class project where
I have some tables like
Table user
user_id | username | name
1 | nihan | Nihan Dip
2 | dip | Meaw ghew
more | more | more
Table Friend
you | friend_id
1 | 2
1 | 27
2 | 9
more | more
Table Follow
user_id | follows
1 | 99
7 | 34
Table post
post_id | user_id | type | content | post_time
1 | 1 | text | loren toren | timestamp
2 | 2 | text | ipsum | timestamp
Now i want to get post by users friend and who he follows and offcourse his so i made this SQL
SELECT
username, name,content, post_time
FROM
post
INNER JOIN
user ON user.user_id = post.user_id
WHERE
post.user_id IN (SELECT
friend_id
FROM
friend
WHERE
you = 1
UNION ALL
SELECT
follows
FROM
follow
WHERE
user_id = 1)
OR post.user_id = 1
ORDER BY post_time DESC
LIMIT 10
this query works just fine. I just wanted to know is there anymore optimization could be done? Then how? Please teach me :)
Instead of using IN try it with JOIN add add few more indexes.
SELECT DISTINCT u.name, u.username,
p.content, p.post_time
FROM post p
INNER JOIN user u
ON u.user_id = p.user_id
INNER JOIN
(
SELECT friend_id id
FROM friend
WHERE you = 1
UNION ALL
SELECT follows id
FROM follow
WHERE user_id = 1
) s ON p.user_id = s.ID
ORDER BY post_time DESC
LIMIT 10

MYSQL Select from 2 tables with an id that is in just in one of them

This is my question:
I have 3 tables:
USERS
USERS_INFO
COMPANIES_INFO
The USERS table has a field ID
The tables USERS_INFO and COMPANIES_INFO have a field ID_USER that is linked by a foreign key with ID.
The question is, how can I select a row that is present in just one of them?
An example:
USERS
+----+
| id |
+----+
| 1 |
+----+
| 2 |
+----+
USERS_INFO
+---------+---------+
| id_user | name |
+---------+---------+
| 1 | Jhonny |
+---------+---------+
COMPANIES_INFO
+---------+---------+
| id_user | company |
+---------+---------+
| 2 | Apple |
+---------+---------+
What I want is something like this:
SELECT * FROM users_info, companies_info WHERE id_user=2
And get this:
id_user = 2
company = Apple
Instead if I did
SELECT * FROM users_info, companies_info WHERE id_user=1
I would have got:
id_user =1
name = Jhonny
I want for example select the user 2, by checking both tables USERS_INFO and COMPANIES_INFO because we don't know which one contains it...
Any help?
Try this:
SELECT U.id
FROM users U
LEFT JOIN users_info UI ON U.id = CI.id_user
LEFT JOIN companies_info CI ON U.id = CI.id_user
WHERE UI.id IS NOT NULL AND CI.id IS NOT NULL
You can try this:
SET #user = 1;
SELECT id_user, name FROM USERS_INFO WHERE id_user = #user
UNION
SELECT id_user, company as name FROM COMPANIES_INFO WHERE id_user = #user;

How to do in Mysql one query to get username and same query to get another username from same users table?

I have two table:
Users Mail
------- ------
ID | Username ID | UserID | SenderID | Something
--------------- ---------------------------------------------------
1 | A 1 | 2 | 1 | Becoming Mad with SQL
2 | B 2 | 3 | 4 | Mee too
I am trying this:
SELECT *
a.userid, a.senderid, a.something,
b.username
FROM
mail a
LEFT JOIN users b on b.id=a.senderid
WHERE
a.id='1'
Output is/similar:
a.Userid | a.senderid | a.something | b.username
--------------------------------------------------
2 | 1 | becoming.. | A
My Expected output is like this (username B and A in one row):
Userid | senderid | something | username | Username of UserID
---------------------------------------------------------------
2 | 1 | becoming..| A | B
How can i get UserID and its Username in the same query? Because i already have left join users b on b.id=a.senderid
SELECT a.userid,
a.senderid,
a.something,
b.username,
c.username
FROM mail a
LEFT JOIN users b ON b.id = a.senderid
JOIN users c ON c.id = a.UserID
WHERE a.id='1'
Use two copies of the users table, one for the sender, one for the user.
SELECT a.userid,
a.senderid,
a.something,
b.username,
c.username
FROM mail a,
users b,
users c
WHERE a.id='1'
AND b.id=a.senderid
AND c.id=a.Userid
Make sure you put indexes in your tables too for mail's id column and users senderid and user id columns - they'll help speed things up.