RimMirK
@RimMirK
Вроде человек. Вроде учусь. Вроде пайтону

Как передавать один параметр, а не 3?

Вот есть вот такой запрос для вывода небольшой статистики
SELECT COUNT(DISTINCT v.id)      AS просмотры,
       COUNT(DISTINCT v.meme_id) AS [уникальные просмотры],
       COUNT(DISTINCT m.id)      AS [выложено мемов],
       COUNT(DISTINCT c.id)      AS [написано комментариев]
  FROM views v JOIN memes m JOIN comments c
 WHERE v.user_id = 1 AND m.user_id = 1 AND c.user_id = 1
но меня смущает что 3 раза повторяется _.user_id = X как можно сократить и не вводить 3 раза?

Пробовал переменные, но sqlite все жалуется мол не существует никаого DECLARE, @user_id не существует и т д
Ошибка при выполнении SQL запроса к базе данных '': near "DECLARE": syntax error
  • Вопрос задан
  • 88 просмотров
Решения вопроса 1
@alexalexes
FROM views v JOIN memes m JOIN comments c
Вы конечно, не указали, в какой СУБД пишете, но странно видеть JOIN без ON или USING.
Если это эквивалент синтаксиса с USING, то вы увидите статистику, если по пользователю есть И просмотры, И мемы, И комментарии. Если в одной из таблиц не будет записей, то пользователь вывалится из статистики.
Если это эквивалент:
FROM views v, memes m, comments c
То такое декартово произведение таблиц с использованием distinct будет не производительно.
Рационально вам написать такое:
SELECT (select COUNT(v.id) from views v where v.user_id = u.user_id )      AS просмотры,
       (select COUNT(DISTINCT v.meme_id) from views v where v.user_id = u.user_id) AS [уникальные просмотры],
       (select COUNT(m.id) from memes m where m.user_id = u.user_id)      AS [выложено мемов],
       (select COUNT(c.id) from comments c where c.user_id = u.user_id)      AS [написано комментариев]
  FROM users u -- лучше связаться с таблицей users
 WHERE u.user_id = 1

Тогда каждый подзапрос будет работать по своей агрегации (да, если по какой-то таблице не будет записей, то вы увидите по ней ноль, а не пустую строчку по всем параметрам), дистинктовать вам нужно только по параметру уникальные просмотры - но его использование не связано с размножением записей при объединении таблиц, так что он посчитает его достаточно быстро.
PS: Если вы не забыли создать индексы для v.user_id, v.meme_id, m.user_id, c.user_id, то должно все летать на космической скорости.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Melkij
@Melkij
PostgreSQL DBA
Потому что необходимо в join описывать критерий объединения. (я вообще думал, что это требование стандарта и в [inner] join синтаксически обязателен on, using или natural)

FROM views v JOIN memes m using(user_id) JOIN comments c using(user_id)
 WHERE user_id = 1
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы