动态行列转换的计算在实际业务中很常见,网上各类技术论坛上都有讨论,比如下面这些问题:
http://www.iteye.com/problems/87788
http://bbs.csdn.net/topics/390869577
http://bbs.csdn.net/topics/391000711
http://bbs.csdn.net/topics/391001035
http://bbs.csdn.net/topics/390888703
http://bbs.csdn.net/topics/391012377
http://bbs.csdn.net/topics/390956910
http://bbs.csdn.net/topics/391004719
http://bbs.csdn.net/topics/390946260
http://bbs.csdn.net/topics/390937222?page=1#post-398564938
http://bbs.csdn.net/topics/390883416
http://bbs.csdn.net/topics/390960953
http://bbs.csdn.net/topics/390959646
行转列使用SQL完成一般有以下几种方法:
<!--[if !supportLists]-->1、 (1)<!--[endif]-->使用行列转换函数
Oracle11g及以上和MSSQL2005+提供了行列转置运算符pivot和unpivot,前者用于行转列,后者用于列转行,使用时需要指定目标列,对于动态列的场景无法直接完成。
<!--[if !supportLists]-->21、 (2)使用CASE表达式
对于不支持pivot的数据库,如Mysql、DB2,可以使用case when条件表达式完成。与pivot类似,需要根据目标列固定写死,无法直接写出动态列结构转换。
对于动态列的情况,只能:
<!--[if !supportLists]-->3、<!--[endif]-->拼接动态SQL
处理动态行列转换时往往需要在存储过程中拼接动态SQL完成,由于数据库间的差异,写法与难易程度也不尽相同,无法编写通用的SQL语句。
实际情况中中,行列转换往往还伴随列间计算,增大了转置时的难度。
行列转换的目的常常是为了进一步的数据呈现,也就是说会有个主程序(如报表工具等)接受结果以进行下一步操作。如果是Java主程序,则可以使用润乾集算器(免费版)来协助完成这类转换。集算器是动态解释执行的脚本,完成行列转换的代码更具通用性。集算器提供了JDBC接口,可以置于Java应用程序与数据库之间,让应用程序继续象访问数据库一样执行集算器脚本,不用改变应用结构。
下面以一个简单的例子说明用集算器如何实现行列转换,并集成进Java主程序中。
1、简单的行转列
一般的行转列只简单地将数据行转为结果列,不涉及复杂的列间计算。如将下面的学生成绩表转为分科目展示的集合:
目标结果:
实现脚本:
A1:执行SQL取数,并按ID、SUBJECT排序;
A2-A3:按ID和SUBJECT分组,集算器保留了分组后的子集供后面计算使用;
A4:动态创建空的目标结果集;
A5-B5:循环A2的学生分组,根据SUBJECT分组将学生ID、姓名和各科目成绩写入结果集;
A6:返回结果集。
从上面代码可以看出采用集算器实现行转列的基本步骤:先动态计算出空的目标结果集(A4),再计算出每行数据追加到结果集中(A5,B5)。在有了支持数据表对象的分步计算机制后,行转列的过程可以按自然思路编写出来。
集算脚本的计算结果可以用JDBC接口返回给JAVA主程序或报表工具,JAVA调用集算脚本代码:
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
//调用集算器脚本(类似存储过程),其中p1是集算器脚本文件名
st =(com. esproc.jdbc.InternalCStatement)con.prepareCall("call p1 ()");
//执行脚本
st.execute();
//获取结果集
ResultSet rs = st.getResultSet();
……
返回值是符合JDBC标准的ResultSet对象,调用集算器脚本和访问数据库的方法完全一样,熟悉JDBC的程序员可以很快掌握。
关于集算器JDBC的部署和调用的更详细信息可参考【集算器集成应用之被JAVA调用】
2、不定长分组的行转列
上一个例子中,结果集的列(即科目)经常可以事先获知,这样用静态的pivot(或case when)语法写出来也不算很困难。但如果结果集的列需要动态计算出来,用pivot就很困难了。如本例中每类机制生产的产品列数不定:
要求根据最大的机组分组长度决定转换后的结果列数,目标结果:
实现脚本:
A1:执行sql从产量表中取数;
A2:按机组分组,在集算器中分组结果保留了分组结果(成员)以方便后续使用和计算;
A3:求分组中最大成员个数,以确定结果集列数;
A4-A5:动态创建空结果集;
A6-B7:循环A2中分组结果,将每个分组中的类别和产量写入A5结果序表中。
与上述类似,这段代码仍然是先动态生成空结果集,然后再计算出合适的数据追加。
本例的计算需要写出动态的SQL来拼出结果集,但由于要找出最大的组才知道列数,拼结果也不是像一般的pivot那样可以用字段值直接对应成列,这就要写存储过程一步步地完成才方便。
相对比较复杂的存储过程,集算脚本支持过程性计算,代码更加简洁、易编写。
3、包含列间计算的行转列
如开始提到的,行列转换的同时往往伴随列间计算,例如有数据:
要求根据指定年份(如2014),输出每月应付金额,若无当月数据,则当月应付金额为上月该值。
目标结果:
实现脚本:
A1:执行SQL取查询年数据;
A2:生成带有12个月的结果空序表;
A3:按客户分组;
A4-B7:循环分组,B5设置相应月份的应付金额,B6将空值置为前一个月的数值,B7将记录插入结果序表中。
运算过程仍然是先产生空结果集后追加数据,不同的是,这里要追加的数据需要经常一系列计算才能得到。
集算脚本支持有序运算,所以很容易取到前一条记录的值。对于动态行列转换时发生的列间计算,与复杂SQL或存储过程相比,集算脚本更清晰易懂。
4、列转行
除了上述提到的转置,有时还有将一行多列数据转为多行数据(列转行)。如下数据,其中列数不定:
目标结果:
实现脚本:
A1:执行SQL取数;
A2:创建目标结果空序表;
A3:根据A1集合的列数计算每条记录要拆分的行数;
A4-B4:循环A1集合,动态获取每列数据插入A2结果序表中;
相关推荐
下面,我们将详细解析如何在Oracle SQL中实现行列转换,并通过具体示例来加深理解。 ### Oracle SQL中的行列转换方法 #### 1. 使用CASE语句 CASE语句是Oracle SQL中实现条件判断的一种方式,它可以根据不同的条件...
行列转换是数据分析中常见的需求,SQL提供了多种方法来实现这一操作: 1. **PIVOT**:某些数据库系统支持Pivot函数,用于将行转换为列。例如,将不同产品的销售额转换为每个产品为一列的形式。 2. **CASE语句**:...
1. **SQL Server中的行列转换**:介绍如何在SQL Server环境中利用内置函数实现数据从行到列的转换。 2. **FOR XML PATH() 函数的应用**:详细解释FOR XML PATH()函数在行列转换中的作用及其实现方法。 3. **动态SQL...
本篇文章将深入探讨一个SQL存储过程的实现方式,该存储过程主要用于完成“行转列”(即行列转换)的操作。通过这种方式,可以有效地将数据库表中的行数据转换为列的形式进行展示或处理,这对于数据分析和报告生成等...
#### 方法二:使用动态SQL实现行列互换 对于科目数量较多的情况,手动编写`CASE WHEN`会变得非常繁琐。此时可以考虑使用动态SQL来简化操作。 ```sql DECLARE @sql VARCHAR(8000); SET @sql = 'SELECT Name AS '; ...
在实际的数据分析和报表制作过程中,我们经常需要将数据的列与行进行互换,这就是所谓的“SQL行列转换”。这种操作在处理汇总数据、创建透视表或者进行特定统计分析时尤其常见。以下我们将详细探讨SQL中的行列转换...
在SQL Server中,行列互转是一种常见的数据处理需求,它能帮助我们以更直观的方式展示数据。本篇文章将深入探讨如何使用聚合函数Pivot和Unpivot来实现这一目标,特别是针对SQL Server数据库。 首先,让我们了解什么...
2. **PIVOT 操作**:如果使用的是支持 PIVOT 的数据库系统(如 SQL Server),那么可以利用 PIVOT 函数来实现行列互换。 #### 四、CASE WHEN + GROUP BY 方法详解 在这个案例中,我们可以使用`CASE WHEN`语句结合`...
总的来说,Oracle 的分析函数提供了一种高效且灵活的方式来进行行列转换,简化了原本复杂的数据处理过程,提升了查询效率。通过理解分析函数的原理和用法,我们可以更好地管理和操作数据库中的数据,适应各种复杂的...
本文将通过一个具体的例子来详细介绍如何在Oracle数据库中实现行列转换。此方法不仅易于理解,而且非常实用,能够帮助用户快速掌握这一技巧。 #### 二、行列转换的基本原理 在开始之前,我们需要了解行列转换的...
### 不定长的SELECT交叉表查询,且不用游标:SQL行列转换技术解析 #### 一、背景介绍 在数据库管理中,数据的组织形式多种多样,有时我们需要将原本存储为行的数据转换成列的形式展示,反之亦然。这种转换在实际...
### Oracle SQL 中的行列互换技术详解 #### 一、引言 在处理数据库查询时,我们经常会遇到需要对查询结果进行格式调整的情况,其中一种常见的需求就是将数据的行列进行互换。例如,原始数据可能按列的形式存储了...
当无法提前知道所有列时,可以使用动态SQL来实现行列转换。 **详细解释:** 1. **构建动态SQL语句:** ```sql DECLARE @sql VARCHAR(8000); SET @sql = 'SELECT 姓名 '; SELECT @sql = @sql + ', max(case 课程...
在SQL数据库管理中,行列转换是一项重要的操作,它允许数据以不同的方式展示,以满足不同场景的需求。在MS SQL Server 2005版本中,微软引入了`PIVOT`和`UNPIVOT`两个关键字,极大地简化了这个过程。本文将详细探讨...
本文档提供了Oracle中行列转换的六个常见案例及其具体实现方法。这些转换技巧对于提高数据库查询效率、简化数据处理流程等方面具有重要意义。通过上述示例的学习,读者可以更好地理解如何利用Oracle的内置功能来满足...
在SQL Server 2005中,我们经常遇到这样的需求:需要将数据库中的多行数据转换为多列显示,这通常被称为“行转列”或“行列互换”。这种操作在数据分析、报表制作或者简化数据显示时非常有用。本文将详细讲解如何在...
总结起来,SQL Server的Pivot功能提供了强大的数据行列转换能力,使得数据的展现更加直观和清晰。掌握这一技巧对于提升数据处理效率和质量具有重要意义。在处理类似的时间序列数据或者分类数据时,Pivot操作尤其有用...
20. 行列转换是一个常见的数据处理问题,通过特定的函数和子查询可以实现数据的行列转换。 21. 连续值和累计值问题关注如何在SQL查询中处理时间序列数据,以及如何生成连续的数值序列或累计值。 22. NULL和DUAL...
4. **PIVOT/UNPIVOT**:这两个操作符提供了行列转换的功能,使得数据透视和数据展开变得更加便捷。 5. **MERGE语句**:MERGE语句用于合并INSERT、UPDATE和DELETE操作,使得数据同步和维护更为简洁。 6. **CLR集成*...