我遇到了一个问题,我可以通过php和一些查询轻松解决,但我想做一个大问题(至少如果它更快,我认为应该是这样)。
所以我有3个表,让我们简化一些:
topic
有3列
access
有2列
friendship
有2列
我想要做的是,如果用户(我们称他为watch_id)正在尝试观看此主题,我想在允许观看的情况下返回主题,或者如果他不是,则不返回任何内容。 他被允许观看其中任何一个是否属实:
正如你所看到的,使用php和一堆查询并不是很难,但在sql中,我无法弄明白。我一直在尝试连接,案例和东西,但逻辑永远不会加起来。 :(
那么你们可以帮助我吗?或者我坚持使用php和大量查询?
编辑:嗯,看起来我并没有让自己完全清楚,我的坏!他被允许观察是否有任何这些要求是真的。由于这种情况,我选择左连接答案,这是最容易扩展的。谢谢大家!
答案 0 :(得分:3)
您应该能够对友谊和访问表进行左连接,以便连接本身不会限制结果:
select something
from topic
left join friendship on friendship.user_id = topic.user_id && friendship.friend_id == watch_id
left join access on access.topic_id = topic.id && access.user_id == watch_id
where
watch_id == topic.user_id or
topic.visibility == 3 or
(topic.visiblity == 2 and friendship.user_id is not null) or
(visibility == 1 && access.topic_id is not null)
答案 1 :(得分:0)
这可以通过一个查询实现,但最简单的方法是使用UNION来合并不同要求的结果。
SELECT t.*
FROM topic AS t
WHERE t.user_id = @watch_id AND t.visibility = 3
UNION ALL
SELECT t.*
FROM topic AS t
INNER JOIN friendship AS f ON f.user_id = t.user_id
WHERE f.friend_id_id = @watch_id AND t.visibility = 2
UNION ALL
SELECT t.*
FROM topic AS t
INNER JOIN access AS a ON a.topic_id = t.id
WHERE a.user_id = @watch_id AND t.visibility = 1
答案 2 :(得分:0)
如果您有三个单独的查询返回您需要的内容,那么您可以考虑在三个结果集上执行联合以获取所需的主题。
基本上,以下内容可以让您返回用户可以观看的所有主题的列表。
select t.topic_id
from topic as t
where t.user_id = watch_id
and t.visibility = 3
union
select t.topic_id
from topic as t
inner join friendship as f
on f.user_id = t.user_id
where f.friend_id = watch_id
and t.visibility = 2
union
select t.topic_id
from topic as t
inner join access as a
on a.topic_id = t.id
where a.user_id = watch_id
and t.visibility = 1
你应该能够用它来获得你所需要的东西。
如果您需要一个可以确认是否可以监视给定topic_id的过程或函数,那么您可以查看是否在上述结果集中包含topic_id
答案 3 :(得分:0)
尝试子查询:
select topic.* from topic
where (topic.user_id = watch_id and visibility=3) or
(topic.user_id = watch_id and visibility=2 and (select count(*) from friendship where friendship.user_id = topic.user_id and friendship_id = watch_id) > 0) or
(topic.user_id = watch_id and visibility=1 and (select count(*) from access where access.topic_id = topic.id and access.user_id = watch_id) > 0)
即使存在多个友谊或访问条目,此解决方案也允许单个主题。看看你的问题,我假设topic.user_id必须等于所有三个的watch_id,但我可能错了。
但是,如果三个表之间只存在一对一的关系,那么左连接是可行的方法。