基于多个徽章分配分配了徽章

大家好
我想根据用户获得特定徽章的次数来授予徽章

  • Alessio 至少获得了 10 次 foo 徽章 → 获得了 Cool_foo 徽章
  • Luca 至少获得了 15 次 foo 徽章 → 获得了 Super_foo 徽章

这是否可以用 SQL 查询实现?

1 个赞

这是可能的。:+1:

您是手动授予(使用数据浏览器 + 大批量授予)还是通过 SQL 触发?

两者都是。其中大部分是手动的,但我正在尝试实现一切自动化。

对于自定义触发器,我认为您应该能够窃取Campaigner查询并对其进行调整,使其适用于徽章而不是邀请。

这个是用于拥有5个“徽章108”,并且设置为每日更新。

SELECT u.id user_id, current_timestamp granted_at
FROM users u
WHERE u.id IN (
    SELECT ub.user_id
    FROM user_badges ub
    WHERE ub.badge_id = 108
    GROUP BY ub.user_id
    HAVING COUNT(*) >= 4
) AND u.active AND u.silenced_till IS NULL AND u.id > 0 AND
    (:backfill OR u.id IN (:user_ids) )

我在我的测试站点上对其进行了简短测试,似乎运行正常(我触发了Badge Grant sidekiq作业来加快等待时间)。但希望这至少能为您提供一个起点。:slightly_smiling_face:

如果您还没有找到,这里还有一些不同的示例可供您参考:Some common badge queries :+1:

3 个赞

谢谢,但我的安装出现了一个错误

> ActiveRecord::PreparedStatementInvalid: missing value for :backfill in /*
>  * DataExplorer Query
>  * Query: /admin/plugins/explorer?id=13
>  * Started by: alefattorini
>  */
> WITH query AS (
> SELECT u.id user_id, current_timestamp granted_at 
> FROM users u 
> WHERE u.id IN ( 
>     SELECT ub.user_id 
>     FROM user_badges ub 
>     WHERE ub.badge_id = 102
>     GROUP BY ub.user_id 
>     HAVING COUNT(*) >= 1
> ) AND u.active AND u.silenced_till IS NULL AND u.id > 0 AND 
>     (:backfill OR u.id IN (:user_ids) )
> ) SELECT * FROM query
> LIMIT 1000

看起来移除
(:backfill OR u.id IN (:user_ids) )

也能很好地工作
这是必须的吗?

看起来您是在数据浏览器中运行的。对于自定义 SQL 徽章,您需要启用隐藏的站点设置,并将查询添加到徽章页面:

但是,根据托管套餐的不同,并非所有人都能够执行此操作。

不过,如果您无法使用自定义 SQL 触发器,数据浏览器中的一个也是完全可行的。:+1: 我认为您需要就运行频率以及如何从结果中授予徽章(手动逐个授予,还是通过批量授予)做出一些选择,但这绝对是可行的。

也许简单的东西会更好,但您或许也想添加一个日期范围参数?

WITH foo AS (SELECT ub.user_id,count(ub.user_id), max(ub.granted_at) granted_at
FROM user_badges ub
WHERE ub.badge_id=108
GROUP BY ub.user_id)

SELECT user_id, granted_at
FROM foo
WHERE count >4
ORDER BY granted_at DESC

我已经启用了此功能。它运行得非常好 :smiley: 谢谢你

1 个赞

太好了。:slightly_smiling_face: 我发现复制现有的徽章查询并进行一些调整,可以很好地帮助我了解从哪里开始。我相信如果您在其中遇到任何问题,它们也可以进一步完善。:+1:

1 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.