Firebird 2.5.8 按球员唯一值聚合 实现队伍号码信息转置为多列
Firebird 2.5.8 球员站位转置实现方案
Firebird 2.5.x版本不支持ROW_NUMBER()等窗口函数,你可以选择以下两种方案实现需求:
方案1:单SQL查询实现(适合小数据量场景)
通过相关子查询给每位球员的记录编号,再用条件聚合转置为多列,完整代码如下:
SELECT t.Player, MAX(CASE WHEN t.StationNo = 1 THEN t.StationInfo ELSE '' END) as "Station 1", MAX(CASE WHEN t.StationNo = 2 THEN t.StationInfo ELSE '' END) as "Station 2", MAX(CASE WHEN t.StationNo = 3 THEN t.StationInfo ELSE '' END) as "Station 3" FROM ( SELECT p.Player, p.Team || ' ' || p.Number as StationInfo, -- 相关子查询生成同球员下的记录序号 (SELECT COUNT(*) FROM 你的原始存储过程名 p2 WHERE p2.Player = p.Player -- 此处可替换为你需要的排序逻辑,比如有转会时间就按转会时间排序 AND p2.Team || CAST(p2.Number AS VARCHAR(10)) <= p.Team || CAST(p.Number AS VARCHAR(10))) as StationNo FROM 你的原始存储过程名 p ) t GROUP BY t.Player
将代码中的你的原始存储过程名替换为你输出Player、Team、Number三列的存储过程名称即可运行。
方案2:自定义存储过程实现(适合大数据量场景,性能更高)
直接创建转置专用存储过程,代码如下:
SET TERM ^ ; CREATE OR ALTER PROCEDURE SP_GET_PLAYER_STATIONS RETURNS ( Player VARCHAR(50), "Station 1" VARCHAR(100), "Station 2" VARCHAR(100), "Station 3" VARCHAR(100) ) AS DECLARE VARIABLE curr_player VARCHAR(50); DECLARE VARIABLE curr_station VARCHAR(100); DECLARE VARIABLE seq INTEGER; BEGIN -- 遍历所有不重复的球员 FOR SELECT DISTINCT Player FROM 你的原始存储过程名 INTO :curr_player DO BEGIN Player = :curr_player; "Station 1" = ''; "Station 2" = ''; "Station 3" = ''; seq = 0; -- 遍历当前球员的所有站位记录,按需求排序 FOR SELECT Team || ' ' || CAST(Number AS VARCHAR(10)) FROM 你的原始存储过程名 WHERE Player = :curr_player -- 此处可替换为实际排序规则 ORDER BY Team, Number INTO :curr_station DO BEGIN seq = seq + 1; IF (seq = 1) THEN "Station 1" = :curr_station; ELSE IF (seq = 2) THEN "Station 2" = :curr_station; ELSE IF (seq = 3) THEN "Station 3" = :curr_station; END SUSPEND; END END^ SET TERM ; ^
存储过程创建完成后,执行以下语句即可得到目标结果:
SELECT * FROM SP_GET_PLAYER_STATIONS;
注意事项
- 请根据你的实际字段长度调整存储过程中VARCHAR的长度定义
- 排序规则可自行修改,比如如果有转会时间字段,优先按转会时间排序可以保证站位顺序符合球员职业生涯真实顺序
- 如果部分球员的站位数量超过3个,按需新增对应Station字段即可
内容的提问来源于stack exchange,提问作者Richard Zelzner
相关产品推荐
相关产品推荐

