我有一个左连接查询来获取用户喜欢的帖子。如果第二次登录用户访问,第一个用户个人资料将显示第一个用户的喜欢,如果第二个用户(登录用户)像同一个帖子那样也会在帖子上显示文字
用户表
user_id | username
喜欢桌子
like_id | post_id | uid
的MySQL
$SQL = "SELECT * FROM likes LEFT JOIN users ON users.user_id = likes.uid WHERE likes.uid = 'user1'"
如果我在上面查询的while循环中运行另一个查询,它将起作用
$check_id = row['post_id']; //get post id from 1st loop
if(isset($_SESSION['userid'])){
$check = "SELECT * FROM likes WHERE post_id='$check_id' AND uid='LOGED-IN-USER-ID'"
}
然后我可以获得num_rows
并添加文字。这项工作非常好但我想知道有没有更好的方法来做到这一点,而不在while循环中运行这么多的查询。有没有办法组合查询或在循环外执行第二个查询。
答案 0 :(得分:2)
那"安全"来自"数据一致性的观点",但在查询后的一段时间内查询称为" 1 + N"并且通常是性能杀手,您可以轻松找到有关SQL 1 + N问题的文档。
解决方案是让SQL服务器在单个查询中为您完成工作,避免与它一起打乒乓球(读取:来回的TCP数据包,查询解析,......)。
假设:
> SELECT * FROM user;
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | root |
| 2 | user2 |
| 3 | user3 |
+---------+----------+
> SELECT * FROM `like`;
+---------+---------+---------+
| like_id | post_id | user_id |
+---------+---------+---------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 4 | 4 | 1 |
| 5 | 2 | 2 |
+---------+---------+---------+
> SELECT * FROM `post`;
+---------+--------+
| post_id | text |
+---------+--------+
| 1 | post 1 |
| 2 | post 2 |
| 3 | post 3 |
| 4 | post 4 |
+---------+--------+
有多种方式可以请求您想要的内容,但有一种方法可能是:
> SELECT like_id, like.post_id, text,
(SELECT 1 FROM `like`
WHERE post_id = post.post_id AND
user_id = 2 /* logged in user */) AS I_like_it_too
FROM `like`
JOIN post USING (post_id)
WHERE user_id = 1 /* user id of seen profile */;
+---------+---------+--------+---------------+
| like_id | post_id | text | I_like_it_too |
+---------+---------+--------+---------------+
| 1 | 1 | post 1 | NULL |
| 2 | 2 | post 2 | 1 |
| 3 | 3 | post 3 | NULL |
| 4 | 4 | post 4 | NULL |
+---------+---------+--------+---------------+
使用I_like_it_too别名根据需要以不同方式显示帖子。
从性能的角度来看,您需要like.user_id
上的索引来限制一小部分上的选定行,依赖子查询只会针对此子集运行,因此这样做了行。
另一种可能性是:
> SELECT displayed.like_id, displayed.post_id, text, my_likes.like_id is not null AS i_also_like
FROM `like` AS displayed
JOIN post USING (post_id)
LEFT JOIN `like` AS my_likes ON
displayed.post_id = my_likes.post_id AND
my_likes.user_id = 2 /* logged user */
WHERE displayed.user_id = 1 /* user id of seen profile */;
+---------+---------+--------+-------------+
| like_id | post_id | text | i_also_like |
+---------+---------+--------+-------------+
| 1 | 1 | post 1 | 0 |
| 2 | 2 | post 2 | 1 |
| 3 | 3 | post 3 | 0 |
| 4 | 4 | post 4 | 0 |
+---------+---------+--------+-------------+
答案 1 :(得分:0)
你的意思是这样吗?
表SO_LIKES(你"喜欢"表)
like_id | post_id | uid
1 | 1 | 1
2 | 2 | 1
3 | 1 | 2
表SO_USERS(您"用户"表)
user_id | username
1 | User1
2 | User2
SQL
SELECT * FROM SO_LIKES as t1 LEFT JOIN SO_USERS as t2 ON t1.uid = t2.user_id INNER JOIN SO_LIKES as t3 ON t1.post_id = t3.post_id WHERE t2.user_id = 1 AND t3.uid = 2
SO只需再次在您的查询中调用相同表,并使用用户2的ID
WHERE t2.user_id = 1 AND t3.uid = 2
输出看起来像这样
like_id | post_id | uid | user_id | username | like_id | post_id | uid
1 | 1 | 1 | 1 | User1 | 3 | 1 | 2
所以你得到了POST_id 1这两个用户都喜欢