简体   繁体   中英

Write SQL count with HAVING sum restrictions in a JOIN without a sub-query in FROM

Suppose there are two tables

    *   -----------------   1
site_visits                sites

site_id | visits          site_id      
1       | 15               1
1       | 10               2
2       | 20               3
2       | 45
3       | 55

The purpose is to count how many sites, have more than 50 visits. The DBMS is MySQL with InnoDB. To be noted, that there must be a join, because there are where clauses on columns from both tables (in the bigger picture).

I've managed to write this with a sub-query in FROM; from the above data, it should yield the value 2, since there are 2 such sites, with id 2 and 3 having sums 65 and 55, while for id 1 the sum is only 25.

select count(*) 
  from (
    select sum(visit.visits) as visits_sum
      from sites site 
      join site_visits visit
      on site.site_id = visit.site_id
      group by site.site_id) as sub_sum
  where visits_sum < 50

However I'd like this written without a sub-query in FROM in order to be able to use it with ORM; what I've managed thus far is:

select count(site.site_id)
  from sites site 
  join site_visits visit
  on site.site_id = visit.site_id
  group by site.site_id 
  having sum(visit.visits) < 50

Without the group by, it sums the whole joined table and yields 3. With it, it returns as many entries as the total count, in this case 2. And the values for these entries are 2 and 1 (since there are 2 entries with id 2 and 1 with id 3 in the joined table). Something like count(count(...)) would probably do it, but that's not allowed.

Ok, if you are using MySQL 8.0.2 and above then you can use window functions. i omit the site table since it is not really necessary for the example.

select distinct count(count(site_visits.site_id)) over ()
from site_visits
group by site_visits.site_id 
having sum(site_visits.visits) > 50

demo

select count(site_id) from (
select site_id from site_visit group by site_id having sum(visits)>50)t

How about this:

select count(1) from
(select a.site_id,sum(visits) as visits_sum  from site_visits a,sites b where 
a.site_id = b.site_id group by a.site_id having sum(visits)>50) as ab

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