Retrieving data information from another table Left Join SQL - sql

User A liked User C Post
Table Users:
id_user name
1 A
2 B
3 C
Table Posts:
id_post post user_post
15 hi 2
19 how are you 3
23 hello 2
Table likes:
id_like id_liker liked_post_id liked_user_id
45 1 19 3
From table likes I show results
User 1 liked post 19 that belongs to user 3
SELECT liked_user_id,_liker,liked_post_id
FROM likes
WHERE liked_user_id = 3
How do I show the next
User A liked User C Post which is "How are you"
I tried but I get an error:
SELECT name
FROM users as u
LEFT JOIN
(SELECT id_post, post, user_post
FROM posts as p
LEFT JOIN
(SELECT liked_user_id, id_liker, liked_post_id
FROM likes
WHERE liked_user_id = 3
) AS b ON u.id_post = b.liked_post_id
) AS c ON u.id_user = c.user_post

SELECT u.`name`, v.`name`, p.post
FROM likes
LEFT JOIN Users as u on likes.id_liker=u.id_user
LEFT JOIN Users as v on likes.liked_user_id=v.id_user
LEFT JOIN Posts as p on likes.liked_post_id=p.id_post
WHERE likes.liked_user_id=3

SELECT liker.name AS liker_name
,liked.name AS liked_name
,p.post
FROM likes AS l
LEFT JOIN Users AS liker ON liker.id_user = l.id_liker
LEFT JOIN Users AS liked ON liked.id_user = l.liked_user_id
LEFT JOIN Posts AS p ON p.id_post = l.liked_post_id
AND l.liked_user_id = p.user_post
WHERE l.liked_user_id = 3

Related

Database join where

Database
Users
id
lastname
firstname
1
Sardor
Sattarov
2
Nurmuhammad
To’xtayev
3
Jasur
Sattarov
Group_items
id
student_id
group_id
1
2
55
2
1
55
3
2
11
Return
example 1
condition
users.id == group_items.student_id do not publish a table that satisfies this desire group_items.id == 55
id
lastname
firstname
3
Jasur
Sattarov
example 2
condition
users.id == group_items.student_id do not publish a table that satisfies this desire group_items.id == 11
id
lastname
firstname
1
Sardor
Sattarov
3
Jasur
Sattarov
Looks like you want OR instead of AND.
SELECT
*
FROM
users u
LEFT JOIN group_items gi ON u.id = gi.student_id
WHERE
gi.student_id IS NULL
OR gi.group_id <> 5
Studends without a group plus studends in all groups but 5.
Please try this,
Example 1:
SELECT
U.ID,U.LASTNAME,U.FIRSTNAME
FROM
USERS U
LEFT JOIN
GROUP_ITEMS G
ON U.ID=G.STUDENT_ID
WHERE G.GROUP_ID <>55
Example 2:
SELECT
U.ID,U.LASTNAME,U.FIRSTNAME
FROM
USERS U
LEFT JOIN
GROUP_ITEMS G
ON U.ID=G.STUDENT_ID
WHERE G.GROUP_ID <>11
You can use join statements in SQL
For Example
for return 1:
SELECT * FROM users u left join group_items gi on gi.student_id = u.id
this query will return all students with their group_id
for filter by group you can use where statement.
SELECT * FROM users u left join group_items gi on gi.student_id = u.id where gi.group_id<>11

Dynamically select the table to join in Postgres with case statements

My notifications table has a column called action_id and trigger_type. I want to INNER JOIN action_id with another table (Like users or posts) depending on the trigger_type. I wrote the following query but it throws an error.
Table structure
users
display_name
username
id
John
Doe
1
Larry
Doe
2
posts
post_title
post_body
id
user_id
Hello
Hello world
1
2
comments
comment_text
post_id
id
user_id
Hello
1
1
1
notifications
read
trigger_id
id
target_id
action_id
trigger_type
false
1
1
2
1
0
false
1
2
2
1
1
trigger_type = 0 means its a like 1 means its a comment
SELECT notifications.*, users.display_name, users.username, users.profile_pic, posts.title
FROM notifications
INNER JOIN users ON users.id = notifications.trigger_id
(
CASE notifications.trigger_type
WHEN 0 THEN INNER JOIN users ON users.id = notifications.action_id
WHEN 1 THEN INNER JOIN posts ON posts.id = notifications.trigger_id
)
You cannot conditionally join like that. Instead, use left join like this:
SELECT n.*,
-- whatever columns you want from the trigger user go here
un.display_name, un.username, un.profile_pic, p.title
FROM notifications n JOIN
users u
ON u.id = n.trigger_id LEFT JOIN
users un
ON un.id = n.action_id AND n.trigger_type = 0 LEFT JOIN
posts p
ON p.id = n.action_id AND n.trigger_type = 1;

Recommended friends one degree separation

I have a table structure
(Xref) IDUser1 and IDUser2 and table IDUser, UserName.
Xref table of friends is bidirectional (1, 2) and (2, 1).
What is the best way to get friends of my friends (that is not my friend) who has at least one of my friend as the mutual friend?
SELECT DISTINCT friendL2.*
FROM [User] me
LEFT JOIN Xref relation1
ON relation1.IDUser1 = me.IDUser
LEFT JOIN Xref relation2
ON relation2.IDUser2 = me.IDUser
INNER JOIN [User] friendL1
ON relation1.IDUser2 = friendL1.IDUser
OR relation2.IDUser1 = friendL1.IDUser
LEFT JOIN Xref relation3
ON relation3.IDUser1 = friendL1.IDUser
LEFT JOIN Xref relation4
ON relation4.IDUser2 = friendL1.IDUser
INNER JOIN [User] friendL2
ON relation3.IDUser2 = friendL2.IDUser
OR relation4.IDUser1 = friendL2.IDUser
WHERE friendL2.IDUser != friendL1.IDUser -- This will tell that this guy can't be your friend
AND me.IDUser = #me
Just replace #me with your current id
You can also modify the last line by the next one if you wish to filter by UserName
AND me.Username = #me
IDUser1 | IDUser2
1 | 2
2 | 1
|
Sory for incomplete question, this is my table Xref, and I have another table User (IDUser, UserName). User with IDUser 1 is friend of IDUser 2 and vice versa.
I have this query for friends of friends
SELECT DISTINCT u.IDUser1,p.Username FROM Xref AS u
inner join User as p on p.IDuser1=u.IDUser1
INNER JOIN (SELECT g.IDUser2 FROM Xref AS g WHERE g.IDUser1 = #IDUsern1
) AS f ON
(u.IDUser2=f.IDUser2 AND u.IDUser1 <> #IDUser2)
WHERE U.IDUser1 NOT IN (Select Xref.IDUser2 from xref
inner join Users on Users.IDUser1=Xref.IDuser1
where xref.IDUser2=#IDUser)
this works great, but I need users who are not my friends but have at least one of my friend as mutual friend

SQL Join to only one record in one to many relationship

I have the following query:
SELECT c.[ClientID]
,u.[AccessId]
FROM [tblClient] c
INNER JOIN [tblUser] u ON u.[Id] = c.[UserId]
This tblUser has multiple ID's for each UserID row.
So it would look like this:
UserID AccessID
1 AD2F0A-965B78414-2B34906F2-0127AA5A
1 ID2F0A9-65B784-142B34906-F20127AA5A
1 UD2F0A9-65B78-4142B34906F-20127AA5A
2 TD2F0A9-65B784142-B34906F-20127AA5A
2 RD2F0A9-65B784142B3-4906-F20127AA5A
3 WD2F0A96-5B784142-B34906F201-27AA5A
3 ZD2F0A96-5B784-142B34-906F2-0127AA5A
3 CD2F0A965-B784142B3-4906F20-127AA5A
Is there a way to only get the top(or 1) AccessId for each UserID? It doesnt matter which AccessID i get, I just want 1 of them.
Thanks
SELECT c.[ClientID], MAX(u.[AccessId])
FROM [tblClient] c
INNER JOIN [tblUser] u
ON u.[Id] = c.[UserId]
GROUP BY c.[ClientID]

Selecting a user's friend's events

I have these information :
Table "Users" =>
**Id** **Name**
1 a
2 b
3 c
4 d
5 e
Table "Friends" =>
**SenderId** **ReceiverId** **State**
1 2 x
2 3 ok
3 1 ok
3 4 ok
5 3 ok
5 4 ok
Table "Events" =>
**SenderId** **receiverId** **text**
1 1 3 ssss
2 3 1 dsadsa
3 2 3 safsdf
4 3 5 fgfdgfd
5 4 3 fgfhgfh
6 5 4 sad sad
My question is that how could I get the events of user's friends in one sql statement using JOINS only .
for example :=>
userId : 1
his friends : 3 (state = ok)
friends events : 1, 2, 3, 4, 5 (events from 1 to 5 have the userId 3 which considered as a friend to user 1 )
ANY HELP .. THANKS ;) !!
You didn't specify a name for the first column in your Events table so I've called it row_ID:
SELECT U1.ID AS user_ID, U1.Name AS user_name,
U2.ID AS friend_user_ID, U2.Name AS friend_user_name,
E1.row_ID, E1.text AS event_text
FROM Users AS U1
INNER JOIN Friends AS F1
ON (
U1.ID = F1.ReceiverId
OR U1.ID = F1.SenderId
)
AND F1.State = 'ok'
INNER JOIN Users AS U2
ON U2.ID = F1.SenderId
INNER JOIN Events AS E1
ON (
U2.ID = E1.ReceiverId
OR U2.ID = E1.senderId
)
WHERE U1.ID = 1;
Your table structure is quite confusing with all those Sender and Receiver ID's, but I think the following query will work.
SELECT * FROM
(SELECT Users.Name, Events.text
FROM Users
LEFT JOIN Friends ON Users.Id = Friends.ReceiverId
LEFT JOIN Events ON Friends.SenderId = Events.SenderId
WHERE Users.Id = 1)
UNION ALL
(SELECT Users.Name, Events.text
FROM Users
LEFT JOIN Friends ON Users.Id = Friends.ReceiverId
LEFT JOIN Events ON Friends.SenderId = Events.ReceiverId
WHERE Users.Id = 1)
You can probably simplify this, but I'm not sure how, considering you want to select events 1-5 because the friend ID can be either the Events.SenderId or the Events.ReceiverId.
I don't know if SQL supports this, but maybe put an OR into the LEFT JOIN clause (?):
SELECT Users.Name, Events.text
FROM Users
LEFT JOIN Friends ON Users.Id = Friends.ReceiverId
LEFT JOIN Events ON (Friends.SenderId = Events.SenderId OR Friends.SenderId = Events.ReceiverId)
WHERE Users.Id = 1
It's pretty easy with a sub-query.
Here's the subquery (find user 1's friends)
SELECT
senderID
FROM
friends
WHERE
receiverID = 1
Here's the main query (find user1's friend's events)
SELECT
primary_key,
senderID,
receiverID,
text
FROM
events
WHERE
senderID IN (subquery) --events where user1's friends were the senders
OR receiverID IN (subquery) --events where user1's friend's were the receivers
Put it all together:
SELECT
*
FROM
events
WHERE
senderID IN (SELECT
senderID
FROM
friends
WHERE
senderID = 1) --events where user1's friends were the senders
OR receiverID IN (SELECT
senderID
FROM
friends
WHERE
receiverID = 1) --events where user1's friend's were the receivers
You might consider replacing the explicit '1' with a variable, so you can run this query for every user.
Good luck