我有一个名为 actions 的简单历史记录表,类似于以下内容:
id | actionable_id | actionable_type | user_id
----------------------------------------------
表格的actionable_types可以是'comment','vote'或'submission',其actionable_id与每个相应表的主键有关。同样,所有评论和投票都属于提交。
此外,我有一个友谊表,类似于以下内容:
id | user_id | friend_id | user_id
----------------------------------
表的user_id属于拥有朋友的用户(friend_id是朋友)。
如果您还没有猜到,每当用户评论,投票或上传新提交时,它都会作为新的“操作”添加到历史记录表中。为单个用户的朋友获取所有操作是快速而直接的,并且到目前为止工作得非常好。但是,这不是我的问题......
我想获取属于当前用户的非朋友群组的所有评论和投票。此外,只有当前用户对同一提交内容进行了投票或评论时,才会选择对提交条目的评论和投票。
因此,我需要进行以下两个查询,假设current_user是当前登录的用户。
查询1 - 所有类型为vote的行为符合以下条件:
查询2 - 符合以下条件的所有类型注释操作:
由于两个查询都在同一个Action表中,因此对我来说理想的是只有一个查询(尽管我认为这是非常不可能的,因为需要大量的JOINS)。
我的主要挂断是与检查非友谊相关的子查询以及每个查询的最后一个条件(current_user至少有一个......)。我将免除你当前的查询代码库,因为它甚至可能不是很接近。
感谢您寻找&帮忙。
答案 0 :(得分:0)
你想要一个复杂的查询。 这是我的建议(假设我已正确理解你的要求:
SELECT a.* FROM actions a
LEFT OUTER JOIN vote v
ON v.id=a.actionable_id AND a.actionable_type='vote'
LEFT OUTER JOIN comment c
ON c.id=a.actionable_id AND a.actionable_type='comment'
WHERE a.user_id<>current_user.id
AND NOT EXISTS (
SELECT 1 FROM friendships f
WHERE f.user_id=current_user.id
AND f.friend_id=a.user_id
) AND EXISTS (
SELECT 1 FROM submission s
LEFT OUTER JOIN vote v1
ON v1.submission_id=s.id
LEFT OUTER JOIN comment c1
ON c1.submission_id=s.id
WHERE (v1.id IS NOT NULL
AND v1.submission_id=v.submission_id
AND v1.id<>v.id
AND v1.user_id=current_user.id) OR
(c1.id IS NOT NULL
AND c1.submission_id=c.submission_id
AND c1.id<>c.id
AND c1.user_ud=current_user.id)
);
所以我抓住所有行动,加入对行动的投票和评论。 然后我过滤掉所有操作与我当前用户具有的user_id相同。 确保该操作不是朋友。 最后我得到提交的内容并加入current_users投票和对他们的评论,当提交的投票或评论存在时,这与所选操作的提交相同,那么我找到了非朋友用户的操作你在寻找。