SELECT user_id, current_timestamp AS granted_at
FROM user_badges
WHERE badge_id = 110 -- Users Helping Users
AND (:backfill OR user_id IN (:user_ids))
GROUP BY user_id
HAVING COUNT(*) >= 5
WITH badge_count AS (
SELECT
user_id,
granted_at,
RANK() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS rank
FROM user_badges
WHERE badge_id = 110
)
SELECT user_id, granted_at
FROM badge_count
WHERE rank IN (5,10,15,20,25,30,35,40,45,50)
さて、2回目の試みとして ROW_NUMBER を使用します。
WITH badge_count AS (
SELECT
user_id,
granted_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS row
FROM user_badges
WHERE badge_id = 110
)
SELECT user_id, granted_at
FROM badge_count
WHERE row % 5 = 0
しかし、さらにテストしたところ、これはプレビューでは正しく機能しますが、実際の badge grant ジョブが実行されるときに複数回付与されません。理由はよくわかりません。
WITH post_count AS (
SELECT
user_id,
id,
created_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at ASC) AS row
FROM posts
WHERE topic_id = 864
)
SELECT user_id, created_at granted_at, id post_id
FROM post_count
WHERE row % 5 = 0
AND (:backfill OR id IN (:post_ids))
WITH badge_count AS (
SELECT
user_id,
granted_at,
post_id,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at DESC) AS row
FROM user_badges
WHERE badge_id = 110
AND post_id IS NOT NULL
)
SELECT user_id, granted_at, post_id
FROM badge_count
WHERE row % 5 = 0
AND (:backfill OR post_id IN (:post_ids))
(AND post_id IS NOT NULLを追加することで、理由なしで付与された場合に保護され、壊れるのを防ぎます)