Trying to JOIN an empty table nothing returns
尝试将空表(注释表)联接到现有的已准备语句时出现问题。
这非常有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // prepare images if ($stmt = $mysqli->prepare(" SELECT uu.*, m.*, ( SELECT COUNT(*) FROM img_likes AS t WHERE t.img_id = uu.imgID AND t.user_id = ? ) AS user_likes, ( SELECT COUNT(*) FROM img_likes AS t WHERE t.img_id = uu.imgID ) AS total_likes FROM user_uploads AS uu INNER JOIN members AS m ON m.id = uu.user_id ORDER BY up_time DESC")) { $stmt->bind_param('i', $user_id); $stmt->execute(); // get imgs // foreach print images // working as expected } |
我不知道为什么如果我加入另一个空的表格(img_comments),图像就不会被打印出来…如果我在表格中添加一行并刷新页面,就会打印一个图像…
我正在尝试但不起作用的声明是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | SELECT uu.*, m.*, ic.*, ( SELECT COUNT(*) FROM img_likes AS t WHERE t.img_id = uu.imgID AND t.user_id = ? ) AS user_likes, ( SELECT COUNT(*) FROM img_likes AS t WHERE t.img_id = uu.imgID ) AS total_likes FROM user_uploads AS uu INNER JOIN members AS m ON m.id = uu.user_id INNER JOIN img_comments AS ic ON ic.img_id = uu.imgID ORDER BY up_time DESC |
号
为什么只打印基于表行数的图像?我也试过左进,但我不太熟悉这个。我只在其他脚本中使用内部联接,而且从未遇到过这样的问题。
我希望对我的查询进行任何优化。
内部联接的作用是什么?它将表A的所有记录与表B的所有匹配记录连接起来,因此当表B中没有记录时,表A的任何记录都不匹配,因此根本没有结果。为什么这会让你吃惊?
左联接是外部联接(左外部联接的简称)。意思是:给我A表的所有记录和B表的所有匹配记录,当没有匹配时,无论如何给我A表的记录。这似乎是你想要的。但你说你试过了。我看不出这在你的问题上会怎样失败。
外部连接不工作的一个典型错误是在WHERE子句中有一些字段b(例如,当b.id>100时)。由于外部联接的记录没有匹配的B记录,因此所有B字段都为空,因此这样的WHERE子句将失败。你只需要再次得到匹配,就像内部连接一样。
编辑:关于优化,可以有条件地一次通过计数得到两个计数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | SELECT uu.*, m.*, ic.*, il.count_user AS user_likes, il.count_total AS total_likes FROM user_uploads AS uu INNER JOIN members AS m ON m.id = uu.user_id LEFT OUTER JOIN img_comments AS ic ON ic.img_id = uu.imgID LEFT OUTER JOIN ( select img_id, count(*) as count_total, count(case when t.user_id = ? then 1 end) as count_user from img_likes group by img_id ) AS il ON il.img_id = uu.imgID ORDER BY uu.up_time DESC; |
据我所知,内部联接将只检索同时具有这两个数据的数据。因此,假设您所联接的表没有具有该联接条件的数据。它不会返回任何数据。
左联接只是普通联接。它将检索两个表上的数据。但是,如果联接的表为空,那么只有主表才有数据,次表的数据将为空。
您只需修改代码,用左联接替换内部联接,然后看看它是否工作。/