简体   繁体   中英

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);

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). 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.

Your query cross joins the fm_inventory and fm_stream tables for each user. 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.

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.

When you mix normal columns with aggregates, include all normal columns in the GROUP BY. In this particular case, you are missing the r.regionName in the GROUP BY.

See longer explanation .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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