前面有两件事。首先,我有一个解决我的问题的方法。我在这里是为了指导它是否是一个好的解决方案,如果我能做得更好。其次,我想为前方的无知道歉!我是一个java人,正在建立一个刚刚进入SQL的网站。我还有很多学习要做的事情,这就是为什么我在这里寻找指导。
我有三个表来处理这个查询。
用于查找所有用户朋友并返回其ID号的SQL语句如下所示。
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
现在我的目标是让Facebook像实时Feed一样。因此,每当用户发布步幅时,他们的所有朋友都会被通知。所以我知道第一步是让所有用户朋友,我在上面这样做了。所以现在我想将这些朋友链接到步幅表。
在步幅表中有sourceUserId(编写步幅的人)和recipientId(收到步幅的人)的列。因此,如果您在自己的电路板上写字并且您的ID是2,那么两列都是2。我的目标是创建一个SQL语句,可以找到所有用户朋友,以及这些朋友在他们的董事会和朋友板上发布的所有帖子。
经过太多的谷歌搜索后,我发现了SQL子查询,并得出了结果。问题是我是新手,不知道这是否是一个好结果,因为我今天才了解这些事情!我害怕可扩展性,如果有100,1000甚至100,000用户,这件事情就会变得混乱!所以我的问题是,
这是我提出的代码!
SELECT * FROM stride WHERE sourceUserId = ANY
(
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
)
AND recipientId = ANY
(
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
)
更新:凭借一堆新知识,我能够为我的实时Feed获得0.0009秒的可靠SQL语句!这是任何有兴趣的人。
SELECT stride.id AS link, sourceUser.userName, sourceUser.displayName, recipientUser.fName AS recipient, sourceUser.currentDefault, stride.content, stride.timestamp,
CASE WHEN (recipientId = sourceUserId) THEN "personalStride" ELSE "friendStride" END AS notType
FROM stride
INNER JOIN user AS sourceUser ON sourceUser.id = stride.sourceUserId
INNER JOIN user AS recipientUser ON recipientUser.id = stride.recipientId
WHERE sourceUserId = ANY
(
SELECT CASE WHEN user1 = 1
THEN user2 ELSE user1 END AS sourceUserId
FROM friends
WHERE user1 = 1 OR user2 = 1
)
AND recipientId = ANY
(
SELECT CASE WHEN user1 = 1
THEN user2 ELSE user1 END AS sourceUserId
FROM friends
WHERE user1 = 1 OR user2 = 1
)
ORDER BY timestamp desc
答案 0 :(得分:0)
您不需要工会:
SELECT
CASE
WHEN f.user1=u.id
THEN f.user2
ELSE f.user1
END AS f_id
FROM user
JOIN friends AS f
ON f.user1=u.id OR f.user2=u.id
WHERE u.id = 1
实际上你也不需要和用户一起加入(当然假设在friends表中的每个id都在users表中有匹配),我只是添加了它,所以我们可以拥有漂亮的“u.id”而不是幻数
SELECT
CASE
WHEN f.user1=2
THEN f.user2
ELSE f.user1
END AS f_id
FROM friends AS f
WHERE f.user1=2 OR f.user2=2
http://sqlfiddle.com/#!2/afb4d/8
修改强> 至于另一个查询,问题有点复杂,我最终得到了这样的查询:
SELECT s.id,s.sourceUserId,s.recipientId
FROM STRIDE as s
JOIN friends AS f
ON
(
((s.sourceUserId=f.user1 OR s.recipientId=f.user1) AND f.user2=1) OR
((s.sourceUserId=f.user2 OR s.recipientId=f.user2)AND f.user1=1)
)
GROUP BY s.id,s.sourceUserId,s.recipientId
HAVING COUNT(*)=2 OR s.sourceUserId=s.recipientId;
http://sqlfiddle.com/#!2/83363/1 如果源或收件人是我们用户的朋友,我们选择该行,我们总结一下,如果该行显示两次,则表示源和收件人都是朋友。我们还会选择source = recipient的那些,因为它们只会出现一次。
子查询很有用,但除非你需要两个不同的聚合,否则它们是可以避免的,并且通常避免它们会更快。