sql - 如何在 PostgreSQL 中动态执行加权随机行选择?

标签 sql postgresql

我有一个应用程序的下表,其中为学生分配了玩教育游戏的任务。

学生{id, last_played_datetime, total_play_duration, total_points_earned}

该应用程序随机选择一名学生并分配任务。学生只需玩游戏即可获得积分。该应用程序记录了玩游戏的日期和时间以及持续了多长时间。我想随机选择一个学生并分配任务。一次只能给一个学生分配任务。为了给所有学生提供平等的机会,我使用学生上次玩游戏的日期和时间、总玩时长和学生获得的总分来动态计算学生的权重。然后将根据体重随机选择一名学生。

在 PostgreSQL 中,我如何根据行的动态计算权重从表中随机选择一行?

每个学生的权重计算如下:(minutes(current_datetime - last_played_datetime) * 0.75 + total_play_duration * 0.5 + total_points_earned * 0.25)/1.5

示例数据:

+====+======================+=====================+=====================+
| Id | last_played_datetime | total_play_duration | total_points_earned |
+====+======================+=====================+=====================+
| 1  | 01/02/2011           | 300 mins            |  7                  |
+----+----------------------+---------------------+---------------------+
| 2  | 06/02/2011           | 400 mins            |  6                  |
+----+----------------------+---------------------+---------------------+
| 3  | 01/03/2011           | 350 mins            |  8                  |
+----+----------------------+---------------------+---------------------+
| 4  | 22/03/2011           | 550 mins            |  9                  |
+----+----------------------+---------------------+---------------------+
| 5  | 01/03/2011           | 350 mins            |  8                  |
+----+----------------------+---------------------+---------------------+
| 6  | 10/01/2011           | 130 mins            |  2                  |
+----+----------------------+---------------------+---------------------+
| 7  | 03/01/2011           |  30 mins            |  1                  |
+----+----------------------+---------------------+---------------------+
| 8  | 07/10/2011           |   0 mins            |  0                  |
+----+----------------------+---------------------+---------------------+

最佳答案

下面是一个解决方案,其工作原理如下:

  • 首先计算每个学生的体重
  • 将所有学生的权重相加并乘以随机种子
  • 然后选择高于该目标的第一个学生,随机,体重

查询:

with 
    student_with_weight as (
        select 
            id,
            (
                extract(epoch from (now() - last_played_datetime)) / 60 * 0.75
                + total_play_duration * 0.5
                + total_points_earned * 0.25
            ) / 1.5 weight
        from student
    ),
    random_weight as (
        select random() * (select sum(weight) weight from student_with_weight ) weight
    )
select id 
from 
    student_with_weight s
    inner join random_weight r on s.weight >= r.weight
order by id
limit 1;

关于sql - 如何在 PostgreSQL 中动态执行加权随机行选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58901823/

相关文章:

SQL查找并删除重复项

sql - 完全外连接仅采用左表(但没有 where 子句)

postgresql - 如何确定在 Postgres 中使用什么类型的索引?

postgresql - 如何使用 PGpoint 使用 PostgreSQL 进行地理定位?

sql - 如何制作我们想要在 PostgreSQL 中查看的 txt/doc/pdf/html 文件

PHP SQL 查询自动完成

mysql - MySQL 的表连接问题

mysql - SQL计算最近7天支付的平均金额

python - postgreSQL 中已定义模式的 PonyORM 多对多关系

mysql - 使用套接字登录 mysql 而不是在终端登录时出现套接字错误