如何在不使用INNER JOIN的情况下连接表格?

时间:2011-01-20 05:51:22

标签: php sql mysql inner-join

我不擅长编写MySQL查询,所以这个查询不能正常工作。我想选择所有“组”,并按组中保存的ID获取组中的外部信息,例如组的创建者,最后更新它的人以及组中的图像数。

在这个查询中,我正在使用INNER JOIN,但显然在此查询中没有选择没有图像的组。我希望查询无论如何都选择所有组,并使用ID获取所有组的信息。如果一个组没有图像,我希望图像计数为0,而不是要忽略的组。

这是当前的查询:

SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by, 
    c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name, COUNT(i.id) as image_count

FROM    gallery_groups g INNER JOIN 
        users c INNER JOIN 
        users u INNER JOIN 
        gallery_images i

WHERE g.created_by=c.id AND g.updated_by=u.id AND i.group=g.id $id
GROUP BY g.name
ORDER BY g.date_updated DESC, g.name

我尝试用LEFT JOIN,RIGHT JOIN和OUTER JOIN替换INNER JOIN,但都只是导致sql错误。

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

将连接条件与它们所属的连接放在一起。 不要混合聚合(列上的总和/最大等)和非聚合(字段不在GROUP BY中而不在函数中),即使MySQL允许你

SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by, 
    c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name, COUNT(i.id) as image_count
FROM    gallery_groups g LEFT JOIN 
        users c ON g.created_by=c.id LEFT JOIN 
        users u ON g.updated_by=u.id LEFT JOIN
        gallery_images i ON i.group=g.id
WHERE g.id = $id
GROUP BY g.id, g.name, g.date_created, g.date_updated, g.created_by, 
    c.fullname, g.updated_by, u.fullname
ORDER BY g.date_updated DESC, g.name

由于您除了图像计数以外几乎所有其他内容进行分组,因此最好只查询子查询

SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by, 
    c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name,
    IFNULL((
        select COUNT(1)
        from gallery_images i
        WHERE i.group=g.id), 0) as image_count
FROM    gallery_groups g LEFT JOIN 
        users c ON g.created_by=c.id LEFT JOIN 
        users u ON g.updated_by=u.id LEFT JOIN
        gallery_images i ON i.group=g.id
WHERE g.id = $id
ORDER BY g.date_updated DESC, g.name

答案 1 :(得分:1)

当你在SQL中连接两个表时,你已经给出了加入的标准。

SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by, 
c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name, COUNT(i.id) as image_count
FROM    gallery_groups g 
    INNER JOIN users c ON g.created_by=c.id
    INNER JOIN users u ON g.updated_by=u.id
    INNER JOIN gallery_images i ON i.group=g.id
GROUP BY g.name
ORDER BY g.date_updated DESC, g.name

首先执行FROM子句,并收集查询返回的所有数据。然后执行GROUP BY和WHERE子句,这将减少将返回的行数。最后执行ORDER BY子句,重新排列整个结果集。

内部和外部联接之间的区别是不匹配发生时的行为。内连接删除不匹配的行,外连接允许不匹配。你几乎总是想要一个内连接,除非你有理由需要外连接。