グループ参加により、実際には数字が膨らんでいると思います(また、全員が信頼レベルに応じた自動グループに属しているため、多少の一貫性のなさがあります)。それらを削除し、トピック、投稿、およびプライベートメッセージに絞り込むためのいくつかの調整を加えることができると思います。
試してみます。
このような感じでしょうか。
-- [params]
-- string :interval = 7 days
SELECT
split_part(ue.email, '@', 2) AS email_domain, -- メールからドメイン部分を抽出
COUNT(p.id) AS "合計投稿数",
COUNT(p.id) FILTER (WHERE p.post_number = 1 AND t.archetype = 'regular') AS "トピック",
COUNT(p.id) FILTER (WHERE p.post_number > 1 AND t.archetype = 'regular') AS "投稿",
COUNT(p.id) FILTER (WHERE t.archetype = 'private_message') AS "個人メッセージ投稿数"
FROM posts p
JOIN user_emails ue ON p.user_id = ue.user_id AND ue.primary = TRUE -- プライマリメールを使用することを保証
JOIN topics t ON t.id = p.topic_id
WHERE p.created_at >= CURRENT_DATE - INTERVAL :interval -- パラメータに基づいて過去x時間の投稿をフィルタリング
AND p.user_id > 0 -- システムユーザー(システムおよびボット)を除外
AND p.deleted_at ISNULL
AND t.deleted_at ISNULL
AND p.post_type <> 3
GROUP BY email_domain
ORDER BY "合計投稿数" DESC -- 結果を投稿数降順で並べ替え