PostgreSQL:基于现有表生成含字母级别的序列数据表
在PostgreSQL中生成扩展范围数据表的实现方法
针对你的需求,我们可以利用PostgreSQL的generate_series函数生成连续序列,结合交叉连接和简单字符转换来实现,以下是完整解决方案:
完整SQL代码
WITH original_table AS ( -- 替换成你的实际表名,或直接用真实表名替代这个CTE SELECT id AS original_id, trim('"' from name) AS name, col, lev FROM your_table_name ) SELECT row_number() OVER (ORDER BY ot.name, col_seq, lev_seq) AS id, ot.name AS "Name", col_seq AS col, chr(64 + lev_seq) AS lev FROM original_table ot CROSS JOIN generate_series(1, ot.col) AS col_seq CROSS JOIN generate_series(1, ot.lev) AS lev_seq ORDER BY id;
关键部分说明
- 生成连续序列:
generate_series(1, ot.col)会为原表每行生成1到该行col值的连续数字,generate_series(1, ot.lev)同理生成1到lev值的数字序列,两个序列交叉连接后得到所有可能的组合。 - 数字转字母:
chr(64 + lev_seq)利用ASCII码转换逻辑,把数字1-7对应转为A-G(ASCII码中A为65,64+1=65,以此类推)。 - 生成自增ID:
row_number() OVER (ORDER BY ot.name, col_seq, lev_seq)按原名称、col序列、lev序列的顺序生成连续ID,和你预期的结果结构一致。 - 处理名称引号:
trim('"' from name)用于移除原表name字段中的双引号,得到干净的名称(如果原表name字段本身无引号,可去掉这部分)。
简化版(直接用原表)
如果你的原表有明确表名(比如racks),可以去掉CTE简化代码:
SELECT row_number() OVER (ORDER BY trim('"' from t.name), col_seq, lev_seq) AS id, trim('"' from t.name) AS "Name", col_seq AS col, chr(64 + lev_seq) AS lev FROM racks t CROSS JOIN generate_series(1, t.col) AS col_seq CROSS JOIN generate_series(1, t.lev) AS lev_seq ORDER BY id;
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

