挙げられた入力では、お望みの出力が得られないと思います。単一のユーザーのデータを取得したい場合、以下のようなクエリが出発点として機能するかもしれません。このクエリは共通テーブル式(CTE)を使用して、読み書きを容易にしています。このパターンを踏襲することで、結果にさらに多くのデータを追加することも可能です。
一つ確信が持てなかったのは、特定の日付におけるデータの合計値が必要なのか、それともその日に行われたアクションの回数が必要なのかという点です。例えば、2019-10-31 時点でユーザーがサイト滞在期間中に作成したトピックの合計数が 20 件であることを知りたいのか、それとも 2019-10-31 当日にユーザーが正確に 3 件のトピックを作成したことを知りたいのか、という点です。現在のクエリの構造では、後者の結果が返されるように設計されています。
--[params]
-- string :username
-- date :start_date
WITH target_user AS (SELECT id FROM users WHERE username = :username),
days AS (
SELECT day::date
FROM GENERATE_SERIES(:start_date, NOW()::date, INTERVAL '1 day') AS day
),
topics_created AS(
SELECT
tu.id,
day,
COUNT(tu.id) AS topics
FROM topics t
JOIN target_user tu
ON tu.id = t.user_id
JOIN days
ON t.created_at::date = day
WHERE t.archetype = 'regular'
AND t.deleted_at IS NULL
GROUP BY day, tu.id
),
posts_created AS(
SELECT
tu.id,
day,
COUNT(tu.id) AS posts,
SUM(array_length(regexp_split_to_array(raw, '\s'), 1)) AS word_count
FROM posts p
JOIN target_user tu
ON tu.id = p.user_id
JOIN days
ON p.created_at::date = day
WHERE p.post_type = 1
AND p.deleted_at IS NULL
GROUP BY day, tu.id
),
likes_received AS (
SELECT tu.id,
day,
COUNT(tu.id) AS likes_received_count
FROM user_actions ua
JOIN target_user tu
ON tu.id = ua.user_id
JOIN days
ON ua.created_at::date = day
WHERE ua.action_type = 2
GROUP BY day, tu.id
)
SELECT
d.day,
COALESCE(topics, 0) AS topics,
COALESCE(posts, 0) AS posts,
COALESCE(word_count, 0) AS word_count,
COALESCE(likes_received_count, 0) AS likes_received
FROM days d
LEFT JOIN topics_created tc
ON tc.day = d.day
LEFT JOIN posts_created pc
ON pc.day = d.day
LEFT JOIN likes_received lc
ON lc.day = d.day
ORDER BY d.day