如何编写SQL实现投资人投资ROUND列的分类(首投标NEW)
投资表新增ROUND分类列的SQL实现
核心判定逻辑非常明确:同一投资人的所有投资记录中,时序最早的那笔标记为NEW,其余所有后续投资统一标记为NOT NEW。题目中已经说明表内投资记录严格按时序排列,投资编号INVESTMENT与时间先后严格正相关,因此可以直接用投资编号的大小作为时序判定的锚点,不需要额外关联时间维度字段。
根据你使用的SQL引擎版本,两种可直接落地的实现方案如下:
方案1:窗口函数实现(推荐,代码简洁性能更优)
适用于支持现代窗口函数的SQL引擎,包括MySQL 8.0+、PostgreSQL、SQL Server、Oracle等,不需要写多层嵌套关联,单次扫描即可完成计算:
SELECT INVESTMENT, INVESTOR, CASE WHEN rn = 1 THEN 'NEW' ELSE 'NOT NEW' END AS ROUND FROM ( SELECT INVESTMENT, INVESTOR, -- 按投资人分组,按投资编号升序排(对应投资时序从早到晚) ROW_NUMBER() OVER ( PARTITION BY INVESTOR ORDER BY INVESTMENT ASC ) AS rn FROM invest_table ) base ORDER BY INVESTMENT;
方案2:通用关联实现(兼容所有SQL版本)
适用于不支持窗口函数的老版本SQL环境,比如MySQL 5.x,通过聚合先算出每个投资人的首笔投资编号,再关联回原表做判断:
SELECT t.INVESTMENT, t.INVESTOR, CASE WHEN t.INVESTMENT = first_invest.invest_id THEN 'NEW' ELSE 'NOT NEW' END AS ROUND FROM invest_table t LEFT JOIN ( -- 计算每个投资人的第一笔投资编号 SELECT INVESTOR, MIN(INVESTMENT) AS invest_id FROM invest_table GROUP BY INVESTOR ) first_invest ON t.INVESTOR = first_invest.INVESTOR ORDER BY t.INVESTMENT;
落地注意事项
- 代码中的
invest_table请替换为你实际存储投资记录的表名即可直接运行。 - 如果后续需要把ROUND值固化为表的实际列,而非查询时动态计算,可以在上述逻辑基础上改造为UPDATE语句:先计算出所有属于
NEW标记的投资编号集合,再批量更新对应行的ROUND值为NEW,其余行默认赋值为NOT NEW即可。 - 若后续表新增了真实的投资时间戳字段,建议把排序锚点从
INVESTMENT编号替换为真实时间戳,避免因编号重置、历史数据迁移导致的时序判定错误。
内容的提问来源于stack exchange,提问作者RalphBiggerton
相关产品推荐
相关产品推荐

