You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MySQL透视表:如何提取各物业当前角色与用户的最新记录?

提取每个物业当前角色对应的用户记录

嘿,这个需求很典型,我来给你分享两种常用的解决思路,都是SQL层面的方案,适合大多数关系型数据库(比如MySQL 8+、PostgreSQL、SQL Server等)。

核心需求拆解

我们需要针对每个property_id(物业)的每个role(角色),只保留创建时间最晚的那条记录——也就是当前担任该角色的用户信息。你的示例里,物业1的Manager角色最新记录是用户67,Resident角色只有用户45,最终要得到这两行。


方法一:用ROW_NUMBER()窗口函数(最常用)

这个方法能精准筛选出每个组内的最新记录,如果有多个记录时间相同,只会保留其中一条(随机)。

WITH ranked_roles AS (
    SELECT 
        property_id,
        user_id,
        role,
        created_at,
        -- 按物业+角色分组,组内按创建时间倒序编号
        ROW_NUMBER() OVER (
            PARTITION BY property_id, role 
            ORDER BY created_at DESC
        ) AS rn
    FROM your_table_name -- 把这里换成你的表名
)
-- 只取每个组里编号为1的(最新的)记录
SELECT property_id, user_id, role, created_at
FROM ranked_roles
WHERE rn = 1;

代码解释

  • PARTITION BY property_id, role:把数据按「物业+角色」拆分成独立的小组,比如物业1的Manager是一个组,物业1的Resident是另一个组。
  • ORDER BY created_at DESC:每个小组内按创建时间从晚到早排序,最新的记录排在最前面。
  • ROW_NUMBER()给每个小组内的行分配编号,最新的记录编号为1,后续的依次递增。
  • 最后筛选rn = 1的行,就是我们要的「当前角色用户」记录。

用你的示例数据运行这个查询,会得到:

property_iduser_idrolecreated_at
167Manager2020-05-19 00:00:00
145Resident2018-03-12 00:00:00

方法二:用RANK()窗口函数(处理同时间的多记录)

如果存在多个用户在同一时间担任同一个物业的同一角色(比如两个用户的created_at完全相同),用ROW_NUMBER()会随机丢弃其中一部分。这时可以换成RANK(),它会给所有时间相同的记录都分配编号1,保留所有最新的记录。

WITH ranked_roles AS (
    SELECT 
        property_id,
        user_id,
        role,
        created_at,
        -- 换成RANK(),同时间的记录会得到相同的编号
        RANK() OVER (
            PARTITION BY property_id, role 
            ORDER BY created_at DESC
        ) AS rn
    FROM your_table_name
)
SELECT property_id, user_id, role, created_at
FROM ranked_roles
WHERE rn = 1;

比如如果物业1有两个Manager的created_at都是2020-05-19,这个查询会把两个用户的记录都返回。


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

火山引擎 最新活动