Как вы можете получить гистограмму отсчетов из таблицы соединений без использования подзапроса? - PullRequest
7 голосов
/ 21 марта 2011

У меня есть много таблиц, которые выглядят так: (id, user_id, object_id).Меня часто интересует вопрос «сколько пользователей имеют один объект? Сколько имеют два? И т. Д.»и хотел бы видеть распределение.

Очевидный ответ на это выглядит следующим образом:

select x.ucount, count(*) 
from (select count(*) as ucount from objects_users group by user_id) as x 
group by x.ucount 
order by x.ucount;

Это приводит к результатам как:

ucount | count
-------|-------
1      | 15
2      | 17
3      | 23
4      | 104
5      | 76
7      | 12

Использование подзапроса здесь чувствуетмне нехорошо, и я бы хотел выяснить, как добиться того же результата без.Кроме того, если вопрос, который вы пытаетесь задать, немного сложнее, он становится беспорядочным, передавая дополнительную информацию из подзапроса.Например, если вы хотите, чтобы данные были дополнительно сгруппированы по дате создания пользователя:

select 
    x.ucount, 
    (select cdate from users where id = x.user_id) as cdate, 
    count(*) 
from (
    select user_id, count(*) as ucount 
    from objects_users group by user_id
) as x 
group by cdate, x.ucount,  
order by cdate, x.ucount;

Есть ли способ избежать взрыва подзапросов?Я полагаю, в конце концов, мое возражение эстетично, но затрудняет чтение и написание запросов.

1 Ответ

1 голос
/ 21 марта 2011

Я думаю, что подзапрос - это абсолютно подходящий способ сделать это, независимо от вашей СУБД. Почему это было бы не элегантно?

Для второго запроса просто присоединитесь к таблице users следующим образом:

SELECT
 x.ucount,
 u.cdate,
 COUNT(*)
FROM (
 SELECT
  user_id,
  COUNT(*) AS ucount
 FROM objects_users
 GROUP BY user_id
) AS x
LEFT JOIN users AS u
 ON x.user_id = u.id
GROUP BY u.cdate, x.ucount
ORDER BY u.cdate, x.ucount
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...