SQL技术咨询:如何用Pivot实现行转列?替代Union多查询方案
用Unpivot实现多列转多行(替代多次Union)
你这里需要的是**逆透视(Unpivot)**操作,而不是Pivot——Pivot是把多行合并成多列,正好和你要的列转多行需求相反。用Unpivot可以一次性完成转换,比写5次Union要简洁易维护,下面给你不同数据库的具体实现:
1. 支持Unpivot语法的数据库(如SQL Server、Oracle)
直接使用UNPIVOT关键字,把你需要拆分的列(包括原TAG列)指定为待转换的列集合即可:
SELECT ID, NAME, UnpivotedTag AS TAG, LOCATION FROM table_one UNPIVOT ( -- 定义转换后的值列别名 UnpivotedTag FOR TagColumns IN ( TAG, -- 保留原TAG列作为一行 TAG_1, TAG_2, TAG_3, TAG_4 ) ) AS UnpivotResult;
代码解释:
UnpivotedTag:是我们给转换后生成的TAG值起的临时别名,最后会重命名为你需要的TAG列TagColumns:是一个虚拟的列名,用来指代原来的TAG、TAG_1等列,不需要在最终结果中出现IN()括号里列出所有需要拆分成行的列,必须包含原TAG列才能保留那一行数据
2. PostgreSQL(无原生Unpivot,用数组+unnest实现)
PostgreSQL可以通过数组和unnest函数实现类似效果:
SELECT ID, NAME, unnest(ARRAY[TAG, TAG_1, TAG_2, TAG_3, TAG_4]) AS TAG, LOCATION FROM table_one;
ARRAY[]把需要拆分的列打包成数组,unnest则把数组的每个元素拆分成单独的行。
3. MySQL(无原生Unpivot,用Union All替代)
如果是MySQL,虽然没有Unpivot语法,但用UNION ALL(比UNION高效,因为不需要去重)也能实现,写法比你之前想的更清晰:
SELECT ID, NAME, TAG, LOCATION FROM table_one UNION ALL SELECT ID, NAME, TAG_1, LOCATION FROM table_one UNION ALL SELECT ID, NAME, TAG_2, LOCATION FROM table_one UNION ALL SELECT ID, NAME, TAG_3, LOCATION FROM table_one UNION ALL SELECT ID, NAME, TAG_4, LOCATION FROM table_one;
注意:
如果你的表中有多条数据,Unpivot和Union All都会正确地对每一行进行拆分转换,不会丢失数据。
内容的提问来源于stack exchange,提问作者user747291
相关产品推荐
相关产品推荐

