【问题标题】:Trying to JOIN an empty table nothing returns尝试加入一个空表没有返回
【发布时间】:2014-11-17 06:07:26
【问题描述】:

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

这是完美的工作:

// 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_cmets),则不会打印图像...如果我在表中添加一行并刷新页面,则会打印一个图像...

我正在尝试但它不起作用的声明是这样的:

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

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

【问题讨论】:

标签: php mysql sql join


【解决方案1】:

内连接有什么作用?它将表 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;

【讨论】:

  • 非常感谢!我没有正确使用它。下次我会研究得更好。 :)
【解决方案2】:

据我所知,INNER JOIN 只会检索同时包含这两个数据的数据。因此,如果假设您加入的表没有具有该连接条件的数据。它根本不会返回任何数据。

LEFT JOIN 只是一个普通的连接。它将检索两个表上的数据。但是如果join的表是空的,那么只有主表有数据,从表有null作为数据。

您可以修改您的代码,将 INNER JOIN 替换为 LEFT JOIN 并查看它是否有效/

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 2022-10-04
    • 2020-12-02
    • 2011-07-19
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多