Как сделать sql более эффективным.Нужен только счет - PullRequest
1 голос
/ 01 июля 2011

Мне нужно найти количество пользователей:

  1. , у которых есть один или несколько поклонников
  2. , у кого два вентилятора
  3. , у которых три вентилятора

Вот sql, который я разработал, чтобы получить ответ на # 1

  SELECT users.id, count(fans.id)
    FROM users 
    JOIN fans on users.id = fans.user_id
GROUP BY users.id
  HAVING COUNT(fans.id) > 0

Вышеупомянутый запрос работает, но я получаю все пользовательские записи, а затем вычисляю размер массива.Он имеет ужасную производительность, когда количество пользователей исчисляется тысячами.Как мне выполнить рефакторинг запроса, чтобы я мог получить только количество пользователей?

Я использую mysql, но мне может понадобиться другой проект, использующий postgresql.

Ответы [ 4 ]

2 голосов
/ 01 июля 2011

Подзапрос будет делать хорошо.

Select 
  Count(user.id) 
from 
  Users 
Where 
  (Select Count(fans.id) from Fans where user_id = users.id) > 0
2 голосов
/ 01 июля 2011

Попробуйте это:

select usersWithOneOrMoreFans = sum( case when t.fan_count >= 1 then 1 else 0 end ) ,
       usersWithTwoFans       = sum( case when t.fan_count =  2 then 1 else 0 end ) ,
       usersWithThreeFans     = sum( case when t.fan_count =  3 then 1 else 0 end )
from ( select user_id as user_id   ,
              count(*) as fan_count ,
       from fans
       group by fans.user_id
     ) t

[отредактировано для удаления бессмысленной ссылки на таблицу]

0 голосов
/ 01 июля 2011

Вот мой:

 SELECT nfans, count(*) AS nusers FROM
     (SELECT count(fans.id) AS nfans FROM fans GROUP BY user_id) foo
 GROUP BY nfans

Это даст вам количество пользователей "nusers", у которых есть поклонники "nfans".

Если вы хотите обрезать выход максимум на 3 вентилятора:

 SELECT nfans, count(*) AS nusers FROM
     (SELECT least(3,count(fans.id)) AS nfans FROM fans GROUP BY user_id) foo
 GROUP BY nfans

В этом случае в корзине «nfans = 3» содержится количество пользователей, у которых есть 3 или более вентиляторов.

0 голосов
/ 01 июля 2011
select num_users_with_fans, num_users_with_two_fans,num_users_with_three_fans
from(
    select count(1) as num_users_with_fans
    from(
        select users.id, count(fans.id)
         from users join fans on users.id = fans.user_id
         group by users.id
         having count(fans.id) > 0
    )a
cross join(
    select users.id, count(fans.id) as num_users_with_two_fans
     from users join fans on users.id = fans.user_id
     group by users.id
     having count(fans.id)=2
)b
cross join(
    select users.id, count(fans.id) as num_users_with_three_fans
     from users join fans on users.id = fans.user_id
     group by users.id
     having count(fans.id)=3
)c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...