简体   繁体   English

MySQL左外部联接和计数-“哪里”?

[英]MySQL Left Outer Join & Count - 'Where'?

I have a relatively simple query that returns a user profile, together with 2 counts related to that user (stream events & inventory); 我有一个相对简单的查询,返回一个用户配置文件,以及与该用户相关的2个计数(流事件和库存);

SELECT u.*, r.regionName, COUNT(i.fmid) AS invcount, COUNT(s.fmid) AS streamcount
FROM fm_users u
JOIN fm_regions r
ON u.region=r.regionid
LEFT OUTER JOIN fm_inventory i
ON u.fmid=i.fmid
LEFT OUTER JOIN fm_stream s
ON u.fmid=s.fmid
WHERE u.username='sampleuser'

Both the inventory & stream values could be zero, hence using a left outer join. 库存和流值都可以为零,因此使用左外部联接。

However, the values for both currently return numbers for all users, not the specific user (always identified as integer 'fmid' in each table). 但是,这两个值当前都返回所有用户的数字,而不是特定用户的数字(在每个表中始终标识为整数“ fmid”)。 This is obviously because the query doesn't specify a 'where' for either count - but I'm not sure where. 这显然是因为查询没有为任何一个计数指定“哪里”-但是我不确定在哪里。 If I change the last part to this; 如果我将最后一部分更改为此;

WHERE u.username='sampleuser' AND s.fmid=u.fmid AND i.fmid=u.fmid
GROUP BY u.fmid

It still returns incorrect numbers, albeit 'different' numbers depending on the search criteria - and the name number for both invcount and streamcount. 它仍然返回错误的数字,尽管“不同”的数字取决于搜索条件-以及invcount和streamcount的名称数字。

Your query cross joins the fm_inventory and fm_stream tables for each user. 您的查询交叉连接每个用户的fm_inventory和fm_stream表。 For example if a specific user has 2 matching fm_inventory rows, and fm_stream also has two, the result will have 4 (=2 x 2) rows and each will be counted in both COUNT() functions. 例如,如果特定用户有2个匹配的fm_inventory行,而fm_stream也有2行,则结果将有4(= 2 x 2)行,并且每个行都将计入两个COUNT()函数中。

The way to accomplish what you are doing is to use correlated subselects for the counts. 完成您的工作的方法是使用相关的子选择进行计数。

SELECT u.*, r.regionName, 
   (select COUNT(*) from fm_inventory i
      where i.fmid = u.fmid) AS invcount, 
   (select COUNT(*) from fm_stream s
      where s.fmid = u.fmid) AS streamcount
FROM fm_users u
JOIN fm_regions r
ON u.region=r.regionid
WHERE u.username='sampleuser'

This allows the counts to be independent of each other. 这允许计数彼此独立。 This works even if more than just one user is selected. 即使选择了不止一个用户,此方法也有效。 In that case you need a group by clause, but otherwise it is the same syntax. 在这种情况下,您需要一个group by子句,但其他语法相同。

When you mix normal columns with aggregates, include all normal columns in the GROUP BY. 当您将普通列与聚合混合时,请在GROUP BY中包括所有普通列。 In this particular case, you are missing the r.regionName in the GROUP BY. 在这种情况下,您在GROUP BY中缺少r.regionName。

See longer explanation . 详见解释

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

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