2013-02-19 148 views
0

我有两个表格:userschanges。我想跟踪每个用户所做的更改次数。目前,我做它在两个单独的语句与PHP结合:LEFT JOIN工作不正常

// Get all users 
$stmt = GlobalContainer::$dbh->prepare("SELECT 
     id, username, realname 
    FROM 
     users 
    ORDER BY role_id, realname"); 
$stmt->execute(); 
while ($user = $stmt->fetch()) { 
    $users[$user['id']] = $user; 
    $users[$user['id']]['changes'] = 0; 
} 

// Get number of changes for each user 
$stmt = GlobalContainer::$dbh->prepare("SELECT COUNT(*) AS `count`, user_id 
    FROM 
     changes 
    GROUP BY user_id"); 
$stmt->execute(); 
while ($changes = $stmt->fetch()) { 
    $users[$changes['user_id']]['changes'] = $changes['count']; 
} 

这工作完全,但我认为这将是整洁,如果我只是把它组合成一个查询。这是我有:

SELECT 
     users.id, users.username, users.realname, count(changes.user_id) as `count` 
    FROM 
     users 
    LEFT JOIN `changes` ON users.id = changes.user_id 
    GROUP BY user_id 
ORDER BY `count` ASC 

但是由于某种原因,它跳过所有但0变化中的一个用户,即使有几个。还有几个用户每个都有3个更改,并且正确显示了所有这些用户。我怎样才能使这个查询工作,以便它显示所有用户0变化?

+0

你能发布数据吗?通过向用户显示0次更改,Didnt不明白你的意思。 – DevelopmentIsMyPassion 2013-02-19 19:28:19

+0

如果该表中没有匹配项,则changes.user_id将返回null。有时候nulls会像COUNT()那样聚集起来。您可以尝试在COUNT()内用零替换零。 – criticalfix 2013-02-19 19:29:28

+0

这似乎解决了它:'GROUP BY users.id'而不是'GROUP BY changes.user_id'。也许有人可以发表解释*为什么*的答案,因为我真的不知道。 – Mike 2013-02-19 19:30:48

回答

3

那么它看起来像一个最近删除的答案是正确的。这是一个细分(和一个demo)。原始查询将nulls分组为一个结果。简单的答案是按非空值进行分组。这使最终查询看起来像这样:

SELECT 
     `users`.id, `users`.username, `users`.realname, count(changes.user_id) as `count` 
    FROM 
     `users` 
    LEFT JOIN `changes` ON users.id = changes.user_id 
GROUP BY `users`.id; 
+0

由于左连接的变化 - 值更改表可以为空,好的捕获。 – Hituptony 2013-02-19 19:43:36

+0

我希望我没有踏上任何人的脚趾重新发布投票回答 – 2013-02-19 19:43:43

+0

我同意 - 删除我的答案,当它downvoted审查的问题,因为我想我可能会误读它.. – dugas 2013-02-19 19:45:15

1

通过更改组:

GROUP BY users.id 
+0

+1你有它第一次:) – 2013-02-19 19:45:49

0
SELECT users.id, users.username, users.realname, count(changes.user_ID) from `changes` as `count` from users 
left join `changes` on users.id = changes.user_id 
group by users.id; 

你计数摆脱你的结果,你可以窝在一个子查询从您的左连接,而这又只能返回行排除计数(changes.user_id)并将它们组合成一条记录。如果使用子查询,则可以在不影响左连接的情况下有效获取changes.user_id的数量。

+0

如果你发现子查询返回相同的结果。我立场纠正。 – Hituptony 2013-02-19 19:38:18

+0

这实际上为每个用户返回相同的值。看起来像所有行中的总数。 – Mike 2013-02-19 19:41:40

+0

感谢您的回复。我编辑了我的答案。 – Hituptony 2013-02-19 19:42:59