我正在构建一个需要与群组或个人用户共享的网站。我知道google不使用mysql的事实,但我想知道如何在我的网站上复制这样的功能。在g +上,可以:
条件:
目前我的数据库表格如下所示。
Circle_category
Cat_id
Cat_name
user_id
帖子
post_id
user_id
post
is_public
all_circle
Post_to_circle
entry_id
post_id
cat_id
Post_to_user
entry_id
post_id
user_id
在家庭圈子中发布用户(在Circle_category中,cat_id为1)可以看到
SQL
SELECT p.* FROM posts p
JOIN Post_to_circle pc
ON p.post_id = pc.post_id
JOIN Post_to_user pu
ON p.post_id = pu.post_id
WHERE p.is_public = 1
OR all_circle = 1
OR pc.cat_id = $cat_id
OR pu.user_id = $user_id
Quetions:
首先,我已经能够从案例1(见所有公开帖子),案例2(与所有圈子分享的帖子)中获得帖子,但其他2个案例不起作用。我想到了它,并看到主要的问题是我指定了where子句来获取p.is_public = 1的帖子,这意味着它在p.is_public = 0的地方行。如何更新查询以便显示覆盖所有的帖子四个案例,也涵盖了我们在开始时谈到的条件。
其次,有没有更好的方法来构建我的表格?我不确定我是以正确的方式做到的。
答案 0 :(得分:2)
从快速阅读的低谷,我只能说:
您正在使用连接语句而不是左连接语句。
使用连接方式: 保留from子句中使用的表中的所有行,该表对于该join子句中指定的条件验证为true。
因为你使用了2个语句,所以第一个连接抛弃了没有所需连接的所有记录,第二个连接抛弃了在第二个连接中没有所需连接的所有记录,但它只使用了匹配第一次加入。
你应该使用左连接。这将保留第一个表中的所有行。所有没有匹配的行,为连接表中指定的列获取值NULL
简单的例子:
用户表:
user_id
name
user_posts
post_id
user_id
content
created
相关查询:
select *
from users u
JOIN user_posts up on up.user_id = u.user_id and up.created > date_sub(curdate(), interval 1 day)
这将使用所有用户并与该用户在一天前创建的每个帖子匹配。 如果用户在最后一天没有帖子,他将不在结果集中。
将此示例更改为
select *
from users u
LEFT JOIN user_posts up on up.user_id = u.user_id and up.created > date_sub(curdate(), interval 1 day)
这将使用所有用户并与该用户在一天前创建的每个帖子进行匹配 如果用户在最后一天没有发布,他仍然会在结果集中,但是posts表中的所有列都将为NULL
where会过滤连接后剩下的所有行。 (mysql将在加入前使用where子句,如果它们可以加速查询)。
更改您的查询:
确保where语句中的子句包含在()之间,用于所有不同的情况。这也不是完整的答案,因为缺少信息(示例用户表,圆关系表,朋友关系)
all_circles选项也让我感到困惑,因此查询中缺少它,但这可以让你走上正确的轨道
SELECT p.* FROM posts p
left JOIN Post_to_circle pc
ON p.post_id = pc.post_id and /* define statement for valid circles for user you're trying to get the posts for */
left JOIN Post_to_user pu
ON p.post_id = pu.post_id and /* define statement for valid friends for user you're trying to get the posts for */
WHERE
/* 1 day old */
p.created > date_sub(curdate(), interval 1 day)
AND (
/* is public */
p.is_public = 1 OR
/* or to friends */
pu.id is not null OR
/* or to circles */
pc.id is not null
)
另外,我怀疑你需要2个子查询,这不是最好的事情,我的建议是为朋友找到所有正确的ID,有效圈子的所有ID,然后使用每个连接语句中的IN子句(注释中的部分)