patternsqlMinor
Incorrect result of query using JOIN of 4 tables
Viewed 0 times
resulttablesincorrectqueryjoinusing
Problem
If someone could help me with the query below it would be great! This query is quite challenging, and I tried to do so on my own, but couldn't display the correct result...
I work with DB of a system that is alike "Facebook".
The query should display the email & name of users who wrote a comment for every post, that posted by each of their friends, in the last year.
Meaning, I would like to display ONLY the people who commented on ALL the posts of ALL their friends.
This is my trial, but I received partial results.
I cannot understand what I have done wrong.
Link to BAK file (including test data):
https://file.io/SagvM3cx
Tables diagram:
EXAMPLES:
Let's assume that I & Adam & Ben are friends.
⭐️ First case:
Then, my name should not display in the query.
Then, my name should display in the query.
⭐️ Second case:
Then, my name should not display in the query.
Then, my name should display in the query.
⭐️ Third case:
Then, my name should display in the query.
EDIT: I added 8 queries - 4
According to this example, the query
I work with DB of a system that is alike "Facebook".
The query should display the email & name of users who wrote a comment for every post, that posted by each of their friends, in the last year.
Meaning, I would like to display ONLY the people who commented on ALL the posts of ALL their friends.
This is my trial, but I received partial results.
I cannot understand what I have done wrong.
select distinct U.Mail, U.FirstName + ' ' + U.LastName as FullName
from Users U
inner join FriendsList FL on U.Mail = FL.Mail1
inner join Post P on FL.Mail2 = P.UserMail
left outer join Comment C on P.ID = C.IDPost and P.UserMail <> C.Mail
where datediff(year, P.DatePosted, getdate()) <= 1
group by U.Mail, U.FirstName, U.LastName
having count(distinct P.ID) = count(distinct C.IDPost)Link to BAK file (including test data):
https://file.io/SagvM3cx
Tables diagram:
EXAMPLES:
Let's assume that I & Adam & Ben are friends.
⭐️ First case:
- Adam wrote 1 post, and I commented.
- Ben wrote 1 post, and I did not comment.
Then, my name should not display in the query.
- Adam wrote 1 post, and I commented.
- Ben wrote 1 post, and I commented.
Then, my name should display in the query.
⭐️ Second case:
- Adam wrote 2 posts, and I commented on the first one but did not comment the second.
- Ben wrote 1 post, and I commented.
Then, my name should not display in the query.
- Adam wrote 2 posts, and I commented both.
- Ben wrote 1 post, and I commented.
Then, my name should display in the query.
⭐️ Third case:
- Adam wrote 2 posts, and I commented both.
- Ben wrote 1 post, and I commented.
- Mark (Not my friend) wrote 1 post, and I did not comment.
Then, my name should display in the query.
EDIT: I added 8 queries - 4
create table and 4 insert.According to this example, the query
Solution
The problem in your original query is that
Should be
You are trying to get comments posted by the original user
Personally I find the double
You are looking for Users where there is no recent post from one of their friends that does not have a comment from that User.
This implements that logic
left outer join Comment C on P.ID = C.IDPost and P.UserMail <> C.MailShould be
left outer join Comment C on P.ID = C.IDPost and U.Mail = C.MailYou are trying to get comments posted by the original user
Personally I find the double
NOT EXISTS approach easier to follow (though the semantics of how to treat Users with no eligible posts to comment on differs).You are looking for Users where there is no recent post from one of their friends that does not have a comment from that User.
This implements that logic
SELECT U.Mail,
U.FirstName + ' ' + U.LastName AS FullName
FROM Users U
WHERE NOT EXISTS (
--A post by one of their friends in the last year
SELECT *
FROM FriendsList FL
INNER JOIN Post P
ON FL.Mail2 = P.UserMail
WHERE U.Mail = FL.Mail1
AND P.DatePosted >= DATEADD(YEAR, -1, GETDATE())
AND NOT EXISTS (
--A comment by the user on that post
SELECT *
FROM Comment C
WHERE P.ID = C.IDPost
AND U.Mail = C.Mail))Code Snippets
left outer join Comment C on P.ID = C.IDPost and P.UserMail <> C.Mailleft outer join Comment C on P.ID = C.IDPost and U.Mail = C.MailSELECT U.Mail,
U.FirstName + ' ' + U.LastName AS FullName
FROM Users U
WHERE NOT EXISTS (
--A post by one of their friends in the last year
SELECT *
FROM FriendsList FL
INNER JOIN Post P
ON FL.Mail2 = P.UserMail
WHERE U.Mail = FL.Mail1
AND P.DatePosted >= DATEADD(YEAR, -1, GETDATE())
AND NOT EXISTS (
--A comment by the user on that post
SELECT *
FROM Comment C
WHERE P.ID = C.IDPost
AND U.Mail = C.Mail))Context
StackExchange Database Administrators Q#266464, answer score: 5
Revisions (0)
No revisions yet.