kolacek
kolacek

Reputation: 11

MySQL multiple joins with multiple counts in one query

I have this query and it works as expected

SELECT i0_.address AS address0, COUNT(d1_.id) AS sclr2 
FROM IP i0_ 
LEFT JOIN Date_IP d3_ ON i0_.id = d3_.ip 
LEFT JOIN Date d1_ ON d1_.id = d3_.date 
GROUP BY i0_.address 
ORDER BY sclr2 DESC

This query also works as expected:

SELECT i0_.address AS address0, COUNT(u2_.id) AS sclr3 
FROM IP i0_ 
LEFT JOIN IP_UserAgent i4_ ON i0_.id = i4_.ip 
LEFT JOIN UserAgent u2_ ON u2_.id = i4_.useragent 
GROUP BY i0_.address 
ORDER BY sclr3 DESC

But How can I combine these two into one?

I tried

SELECT i0_.address AS address0, COUNT(d1_.id) AS sclr2, COUNT(u2_.id) AS sclr3 
FROM IP i0_ 

LEFT JOIN Date_IP d3_ ON i0_.id = d3_.ip 
LEFT JOIN Date d1_ ON d1_.id = d3_.date 

LEFT JOIN IP_UserAgent i4_ ON i0_.id = i4_.ip 
LEFT JOIN UserAgent u2_ ON u2_.id = i4_.useragent 

GROUP BY i0_.address 
ORDER BY sclr2 DESC

In this case value sclr2 is right but sclr3 is the same as sclr2. What Am I doing wrong please?

Upvotes: 0

Views: 47

Answers (2)

Gordon Linoff
Gordon Linoff

Reputation: 1269503

You can combine these by making them subqueries:

SELECT t1.address0, t1.sclr2, t2.sclr3
FROM (SELECT i0_.address AS address0, COUNT(d1_.id) AS sclr2 
      FROM IP i0_ LEFT JOIN 
           Date_IP d3_ ON i0_.id = d3_.ip LEFT JOIN
           Date d1_
           ON d1_.id = d3_.date 
      GROUP BY i0_.address
     ) t1 JOIN
     (SELECT i0_.address AS address0, COUNT(u2_.id) AS sclr3 
      FROM IP i0_ LEFT JOIN
           IP_UserAgent i4_
           ON i0_.id = i4_.ip LEFT JOIN
           UserAgent u2_
           ON u2_.id = i4_.useragent 
      GROUP BY i0_.address
     ) t2
     on t1.address0 = t2.address0;

As mentioned in another answer, count(distinct) can also work. However, it produces an intermediate table which is the cartesian product of the "dates" and the "user agents". So, if there are 100 dates and 100 user agents, the intermediate table would have 10,000 rows -- and if your data has many examples of this, then the processing time and intermediate storage requirements can become prohibitive.

Upvotes: 1

GolezTrol
GolezTrol

Reputation: 116100

Try using

COUNT(DISTINCT d1_.id) AS sclr2, COUNT(DISTINCT u2_.id)

Upvotes: 0

Related Questions