2009-10-01 134 views
1

我有这样的查询:如何使LEFT JOIN与MySQL中的分组/计数工作?

SELECT type.id, type.name, COUNT(*) AS tot 
FROM page 
LEFT JOIN type ON page.type=type.id 
GROUP BY type.id 

然而,这并不能选择所有的类型:它忽略掉那些没有在页表还没有任何类型的。我只想让它列出每个类型的数字,表示有多少页面有这种类型,其中包括0类型不会发生的地方。我需要不同的连接吗?

回答

3

改为做一个RIGHT JOIN。试试这个:

SELECT type.id, type.name, COUNT(page.type) AS tot 
FROM page 
RIGHT JOIN type ON page.type=type.id 
GROUP BY type.id 

请注意不同的计数方式。对于没有 页面的类型,page.type将为NULL。当做这些行时将被忽略COUNT

[编辑]这里是一个例子。如果我们有如下的数据:

 
    type 
id name 
1  A 
2  B 
3  C 

    page 
id type 
1  1 
2  1 
3  2 

如果我们这样做了JOIN喜欢在我的答案(没有GROUP BYCOUNT),我们的结果集将是这样的:

 
type.id type.name page.id page.type 
     1   A  1   1 
     1   A  2   1 
     2   B  3   2 
     3   C  NULL  NULL 

现在,当我们做一个GROUP BYCOUNT(type.id),我们正在计数行 其中type.id不为NULL。这将是所有行:结果是2对于 和1 B和C.

如果我们这样做,而不是COUNT(page.type),我们可以得到2 A,1 B和0 C(因为 page.typeNULL对于C !)

+0

我在正确阅读你的答案之前使用了count(*),并且丢失的类型返回2作为计数。使用像你说的count(page.type)给出0.为什么会发生这种情况? – DisgruntledGoat 2009-10-01 19:18:56

+0

看来,使用count(type.id)也返回2。 – DisgruntledGoat 2009-10-01 19:30:25

+1

'COUNT(*)'统计所有行。 'COUNT(page.type)'只对page.type不为NULL的行进行计数。当你在我的答案中进行JOIN时,没有'pages'的'types'的行将所有'page'列设置为NULL。当我们做'COUNT(page.type)'时,我们只计算有'页面'的'类型'的行(页面列不为空)。 – hrnt 2009-10-01 19:42:55

0

USE合并成NULL值,以GROUP BY

SELECT 
    COALESCE(type.id, 0), 
    COALESCE(type.name, 'NoType'), 
    COUNT(*) AS tot 
FROM 
    page 
LEFT JOIN 
    type 
ON 
    page.type=type.id 
GROUP BY 
    COALESCE(type.id, 0), 
    COALESCE(type.name, 'NoType') 
2

左连接带回所有从表中的行上联接表达式的左侧,不管它们在桌子上存在的权利侧面试试这个(切换表达式的两边):

SELECT type.id, type.name, COUNT(*) AS tot 
FROM type 
LEFT JOIN page ON type.id=page.type 
GROUP BY type.id, type.name