简体   繁体   English

试图加入一个空表没有任何回报

[英]Trying to JOIN an empty table nothing returns

I have a problem trying to JOIN an empty table (comments table) to my existing prepared statement. 我在尝试将空表(注释表)加入现有的准备好的语句时遇到问题。

This is working perfectly: 这非常正常:

// 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
}

And I don't know why if I JOIN another table (img_comments) that is empty, the images are not printed... if I add a row to the table and refresh the page, one image is printed... 而且我不知道为什么如果我加入另一个为空的表(img_comments),则不会打印图像...如果我在表中添加一行并刷新页面,则会打印一个图像...

The statement that I'm trying and it's not working is this: 我正在尝试但不起作用的语句是这样的:

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

Why is only printing images based on the number of the table rows?? 为什么仅根据表格行数打印图像? I also tried LEFT JOIN but I'm not too familiareize with this. 我也尝试过LEFT JOIN,但是我对此不太熟悉。 I only use INNER JOIN in other scripts and I never had a problem like this. 我只在其他脚本中使用INNER JOIN,而我从来没有遇到过这样的问题。

I would appreciate any optimization to my query. 我希望对查询进行任何优化。

What does an inner join do? 内部联接有什么作用? It joins all records of table a with all matching records of table b. 它将表a的所有记录与表b的所有匹配记录连接在一起。 So when there are no records in table b, there is no match for any record of table a, hence no result at all. 因此,当表b中没有记录时,表a中的任何记录都不匹配,因此根本没有结果。 Why does this surprise you? 为什么这会让您感到惊讶?

A left join is an outer join (short for LEFT OUTER JOIN). 左联接是外部联接(LEFT OUTER JOIN的缩写)。 It means: Give me all records of table a with all matching records of table b, and when there is no match then give me the record of table a anyhow. 这意味着:给我表a的所有记录以及表b的所有匹配记录,如果没有匹配项,就给我表a的记录。 This seems to be what you are wanting here. 这似乎就是您想要的。 But you say you tried it. 但是你说你试过了。 I don't see how this would fail in your query. 我看不出这在您的查询中将如何失败。

A typical error for an outer join not to work would be to have some field of b in your where clause (eg where b.id > 100). 外部联接不起作用的典型错误是在where子句中包含b的某个字段(例如,where b.id> 100)。 As the outer-joined records have no matching b record, all b fields are null, so that such a where clause would fail. 由于外部联接的记录没有匹配的b记录,因此所有b字段都为null,因此where子句将失败。 You'd just get matches again, just like with the inner join. 您将再次获得匹配,就像内部联接一样。

EDIT: As to optimization, you can get the two counts in one pass by counting conditionally: 编辑:至于优化,您可以通过有条件地计数来一次获得两个计数:

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;

As far as I know, INNER JOIN will only retrieve data which have both data. 据我所知,INNER JOIN将仅检索同时具有这两个数据的数据。 So if let say the table that you join have no data with that join condition. 因此,如果说您联接的表没有该联接条件的数据。 It will not return any data at all. 它根本不会返回任何数据。

LEFT JOIN is just a normal join. LEFT JOIN只是一个普通的联接。 It will retrieve data on both table. 它将在两个表上检索数据。 But if the joined table is empty, then only the primary table will have data, the secondary table will have null as its data. 但是,如果联接表为空,则只有主表将具有数据,辅助表将具有null作为其数据。

You can just modify your code, replacing INNER JOIN with LEFT JOIN and see if it works/ 您可以修改您的代码,将INNER JOIN替换为LEFT JOIN,然后查看它是否有效/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM