You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按规则为学生图书借阅记录排序生成row_number列的实现方法

SQL实现方案

以下为适配MySQL 8.0及以上版本的实现代码,其他数据库仅需调整字符串截取、类型转换函数即可:

SELECT 
    Student_id,
    Book_id,
    class_id,
    `timestamp`,
    CASE 
        -- 同学生+同图书分组下所有时间均为空,统一行号为1
        WHEN MAX(`timestamp`) OVER (PARTITION BY Student_id, Book_id) IS NULL THEN 1
        -- 分组内存在有效时间,有值记录行号为1,空值记录行号为2
        ELSE ROW_NUMBER() OVER (
            PARTITION BY Student_id, Book_id 
            ORDER BY CASE WHEN `timestamp` IS NOT NULL THEN 0 ELSE 1 END ASC
        )
    END AS row_number
FROM 你的表名
-- 按图书数字部分从高到低排序输出
ORDER BY Student_id, CAST(SUBSTRING(Book_id, 3) AS UNSIGNED) DESC;

逻辑说明

  • 规则1适配:使用SUBSTRING(Book_id, 3)截取图书ID第三位开始的数字部分,转整数后降序排序,保证数字大的图书排在前面。
  • 规则2适配:按学生ID+图书ID分组,组内按时间是否非空排序生成行号,非空记录优先级更高。
  • 规则3适配:先判断分组内是否存在有效时间,全部为空的情况下所有记录行号统一赋值为1。

Python Pandas实现方案

如果用Python做数据处理,可参考以下代码:

import pandas as pd

# 读取数据,此处替换为你的数据读取逻辑
# df = pd.read_csv("你的数据集路径")

# 提取图书ID的数字部分
df["book_num"] = df["Book_id"].str[2:].astype(int)

# 按规则生成行号
df["row_number"] = df.groupby(["Student_id", "Book_id"]).apply(
    lambda group: [1] * len(group) if group["timestamp"].isna().all() 
    else group["timestamp"].isna().rank(method="min", ascending=True)
).reset_index(drop=True)

# 按要求排序,删除辅助列
df = df.sort_values(by=["Student_id", "book_num"], ascending=[True, False]).drop("book_num", axis=1)

# 输出结果
print(df)

内容的提问来源于stack exchange,提问作者Matias021

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:57:02