如何创建SQL视图将表中同ID多行数据转为扩展多列的单行结果
解决方案
你需要实现的是**动态行转列(宽表透视)**需求,以下是几种免硬编码关联的高效方案:
方案1:动态SQL自动生成视图(全数据库通用,性能最优)
完全不需要手动写50次关联逻辑,通过脚本自动生成透视语句,执行后即可得到符合要求的视图,后续最大地址条数变动时重新跑一次脚本即可更新视图:
- 先给相同Id的地址加行号标记:用窗口函数
ROW_NUMBER() OVER(PARTITION BY Id ORDER BY 排序字段) AS rn,每个地址会对应1、2……N的序号 - 用字符串拼接逻辑自动生成每组地址的提取语句,无需手动编写50组列逻辑
- 拼接为
CREATE VIEW语句执行即可完成视图创建
以下是MySQL环境的示例代码:
-- 1. 自动生成所有地址列的提取逻辑 SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(CASE WHEN rn = ', rn, ' THEN Address END) AS Address_', rn, ', ', 'MAX(CASE WHEN rn = ', rn, ' THEN `Address 1` END) AS Address1_', rn, ', ', 'MAX(CASE WHEN rn = ', rn, ' THEN Postcode END) AS Postcode_', rn ) ) INTO @sql FROM ( -- 可手动加WHERE rn <=50限制最大列数 SELECT ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Id) AS rn FROM 你的表名 ) AS ranks; -- 2. 拼接为完整的视图创建语句 SET @sql = CONCAT('CREATE VIEW 你的视图名 AS ', 'SELECT Id, ', @sql, ' FROM (', 'SELECT *, ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Id) AS rn FROM 你的表名', ') AS t GROUP BY Id;'); -- 3. 执行语句生成视图 PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
该方案生成的视图性能和手动编写的静态透视视图完全一致,没有额外查询开销。
方案2:内置PIVOT函数方案(适配支持透视语法的数据库)
如果你使用的是SQL Server、PostgreSQL等支持PIVOT语法的数据库,可以用内置透视函数简化语句,逻辑和动态SQL方案一致,仅用PIVOT关键字替代CASE WHEN判断,语法更简洁。
方案3:结构化聚合方案(轻量最高效,适配非强制分列的场景)
如果业务侧可以接受结构化存储格式,不需要把每个地址拆成单独列,可以直接用聚合函数生成JSON格式的地址列表,无需调整视图结构即可适配任意数量的地址:
-- MySQL示例 CREATE VIEW 你的视图名 AS SELECT Id, JSON_ARRAYAGG( JSON_OBJECT('Address', Address, 'Address1', `Address 1`, 'Postcode', Postcode) ) AS address_list FROM 你的表名 GROUP BY Id;
业务侧取数时直接解析JSON即可,是所有方案中查询性能最高的。
内容的提问来源于stack exchange,提问作者TripleD
相关产品推荐
相关产品推荐

