php - 尝试加入空表没有返回

标签 php mysql sql join

我在尝试将空表(评论表)加入到我现有的准备好的语句中时遇到问题。

这工作完美:

// 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,从来没有遇到过这样的问题。

如果对我的查询有任何优化,我将不胜感激。

最佳答案

内连接有什么作用?它将表 a 的所有记录与表 b 的所有匹配记录连接起来。因此,当b表中没有记录时,a表中的任何记录都没有匹配,因此根本没有结果。为什么这会让您感到惊讶?

左连接是外连接(LEFT OUTER JOIN 的缩写)。意思是:给我a表的所有记录和b表所有匹配的记录,当没有匹配时无论如何给我a表的记录。这似乎就是你想要的。但你说你试过了。我不明白这会在您的查询中失败。

外连接不起作用的一个典型错误是在 where 子句中包含 b 的某些字段(例如,where 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;

关于php - 尝试加入空表没有返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26966524/

相关文章:

php - 在Mac上使用vscode和mamp的php可执行文件的路径

MySQL - 连接所有子记录都有值的记录

sql - 当列值相同时,如何在 postgres 中合并行,并根据合并的行对另一列求和?

使用 Case 的 SQL 数据范围

php preg_split 不识别空格

php - PHP 中的多个 MySQL 查询,已跳过

php - Laravel Eloquent Relationships - 两个不同的送货地址与一个订单模型相关联

php - Doctrine QueryBuilder 按字段优先级排序结果

php javascript json 解析转义字符

php - laravel中获取当前登录用户的数据