我在尝试将空表(注释表)加入到现有的预准备语句时遇到问题。
这完美地运作:
// 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)为空,则不打印图像...如果我在表格中添加一行并刷新页面,则会打印一张图像。 ..
我尝试过的声明并且它不起作用是这样的:
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
为什么只根据表行数打印图像?我也试过LEFT JOIN,但我并不太喜欢这个。我只在其他脚本中使用INNER JOIN,我从来没有遇到这样的问题。
我希望对我的查询进行任何优化。
答案 0 :(得分:2)
内连接有什么作用?它将表a的所有记录与表b的所有匹配记录连接起来。因此,当表b中没有记录时,表a的任何记录都不匹配,因此根本没有结果。为什么这让你感到惊讶?
左连接是外连接(LEFT OUTER JOIN的缩写)。它意味着:给我表a的所有记录以及表b的所有匹配记录,当没有匹配时,无论如何都给我表a的记录。这似乎是你想要的。但是你说你试过了。我不知道你的查询会如何失败。
外连接不起作用的典型错误是在where子句中有一些b的字段(例如,b.id> 100)。由于外连接记录没有匹配的b记录,所有b字段都为空,因此这样的where子句将失败。您只需再次获得匹配,就像内部联接一样。
编辑:至于优化,您可以通过有条件地计算一次获得两个计数:
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;
答案 1 :(得分:0)
据我所知,INNER JOIN只会检索包含两个数据的数据。因此,如果假设您加入的表没有该连接条件的数据。它根本不会返回任何数据。
LEFT JOIN只是一个普通的连接。它将检索两个表上的数据。但是如果连接表为空,那么只有主表将有数据,辅助表将以其数据为空。
您可以修改代码,用LEFT JOIN替换INNER JOIN并查看它是否有效/