我需要你的帮助。基本上,我有4个表:帖子,用户,友情和 favourite_posts 。
我需要选择用户的所有帖子及其朋友的帖子。另外,我需要在结果集中包含最喜欢的帖子。
到目前为止,这就是我所做的:
SELECT DISTINCT p.title, p.post_id, p.user_id, fp.post_id
FROM posts AS p
LEFT OUTER JOIN favourite_posts AS fp
ON p.post_id = fp.post_id
JOIN users AS u
ON p.user_id = u.user_id
LEFT JOIN friendship AS f
ON p.user_id = f.user_id
OR p.user_id = f.friend_id
WHERE p.user_id = 1
OR f.friend_id = 1
AND fp.user_id = 1
AND f.status = 1
SCHEMA:
CREATE TABLE posts
(`post_id` int, `title` varchar(11), `user_id` int);
INSERT INTO posts
(`post_id`, `title`, `user_id`)
VALUES
(1, 'Hello World', 1),
(2, 'Hola Mundo', 2),
(3, 'Ola Mundo', 1),
(4, 'Hi Mundo', 4),
(5, 'Test 1', 1),
(6, 'Test 2', 2),
(7, 'Test 3', 3),
(8, 'Test 4', 4),
(9, 'Test 5', 1),
(10, 'Test 6', 2);
CREATE TABLE users
(`user_id` int, `name` varchar(7));
INSERT INTO users
(`user_id`, `name`)
VALUES
(1, 'George'),
(2, 'Michael'),
(3, 'Learns'),
(4, 'To Rock');
CREATE TABLE friendship
(`friendship_id` int, `user_id` int, `friend_id` int, `status` int);
INSERT INTO friendship
(`friendship_id`, `user_id`, `friend_id`, `status`)
VALUES
(1, 1, 2, 1),
(2, 1, 3, 1),
(3, 2, 1, 1),
(4, 2, 4, 1);
CREATE TABLE favourite_posts
(`fp_id` int, `post_id` int, `user_id` int);
INSERT INTO favourite_posts
(`fp_id`, `post_id`, `user_id`)
VALUES
(1, 1, 1),
(2, 1, 3),
(3, 2, 1),
(4, 2, 4);
您可以测试我的SQLFiddle here
在我的例子中,我需要获得用户#1的所有帖子(包括他的朋友和最喜欢的帖子)
用户1有4个帖子
用户2有3个帖子
用户3有1个帖子
用户1有2个最喜欢的帖子
结果应该总数为8(即8个帖子),但我只得到5.您认为我的查询有什么问题?我很乐意感谢任何帮助。谢谢!
答案 0 :(得分:0)
编辑: 我进入了小提琴,意识到你正在向后运行友谊JOIN和WHERe。友谊是一种单向关系。如果你从POSTS开始,该用户可能会将我作为朋友,但我可能不会将他们作为朋友。
在你的例子中,只有第2个人有1个人作为朋友,但是2个人和3个人都是1的朋友。因此你没有得到8行。
此查询产生8行:
SELECT DISTINCT p.title, p.post_id, p.user_id, fp.post_id
FROM posts AS p
LEFT OUTER JOIN favourite_posts AS fp
ON p.post_id = fp.post_id
JOIN users AS u
ON p.user_id = u.user_id
LEFT JOIN friendship AS f
ON p.user_id = f.friend_id
WHERE p.user_id = 1
OR (f.user_id = 1
AND f.status = 1)
另请注意: OR和AND具有相同的优先级和从左到右的过程。尝试在AND之间明确区分OR,因为它会产生微妙的错误:
WHERE (p.user_id = 1
OR f.friend_id = 1)
AND fp.user_id = 1
AND f.status = 1
添加括号。否则,您的查询等同于:
WHERE p.user_id = 1
OR (f.friend_id = 1
AND (fp.user_id = 1
AND f.status = 1))
此外,您执行LEFT JOIN,因此fp可以具有空值。实际上你只想选择喜欢的帖子吗?你真的应该这么说吗?
WHERE p.user_id = 1
OR (f.friend_id = 1
AND f.status = 1)