要用sql实现的确不是很容易,因为要用关系数据库表示这种非关系数据结构。可以考虑先自定义一个函数f_getprodsal(prodname varchar2,monthname varchar2)取产品在某个月的销售数据。然后在sql中进行引用。
select prodname,f_getprodsal(prodname,1),f_getprodsal(prodname,2),f_getprodsal(prodname,3)....,f_getprodsal(prodname,12)
from prod_tab
select prodname,f_getprodsal(prodname,1),f_getprodsal(prodname,2),f_getprodsal(prodname,3)....,f_getprodsal(prodname,12)
from prod_tab
select 产品,
sum(decode(月份,1,卖出金额,0) as 一月,
sum(decode(月份,2,卖出金额,0) as 二月,
...
from ...
select 产品,
sum(decode(月份,1,卖出金额,0)) as 一月,
sum(decode(月份,2,卖出金额,0)) as 二月,
...
from ...
----------------------
存储过程中可以使用动态sql来建立表,存储过程也可以返回结果。
sql := 'create ...';
execute immediate sql;-------------
创建返回结果集
create or replace package pkg_test as
/* 定义ref cursor类型
不加return类型,为弱类型,允许动态sql查询,
否则为强类型,无法使用动态sql查询;
*/
type myrctype is ref cursor;--函数申明
function get return myrctype;
end pkg_test;
/create or replace package body pkg_test as
--函数体
function get return myrctype is
rc myrctype; --定义ref cursor变量
sqlstr varchar2(500);
begin
open rc for select id,name,sex,address,postcode,birthday from student;
return rc;
end get;end pkg_test;
的静态方法,用来根据传入的参数来拼造一个符合条件的SQL语句,然后用JDBC API执行。
效果还不错,使用起来也很方便^_^。下面是这个Java类的源码:
public class CrossReport {
public CrossReport() {
} /**
*
* @param tableName 要统计的表或者视图的名称
* @param abscissaCol 横坐标列
* @param ordinateCol 纵坐标列
* @param valueCol 值列
* @param strWhere 附加的Where条件
* @return 查询到的结果集,以ResultObj对象形式返回
*/
public static ResultObj getCrossReportData(String tableName,
String abscissaCol,
String ordinateCol,
String valueCol,
String strWhere) {
String strSQL = "select distinct " + ordinateCol + " from " + tableName +
" " + strWhere;
System.out.println("第一次生成的SQL:" + strSQL);
DBOperate dbOperate = new DBOperate();
ResultObj ordinateColData = dbOperate.Query(strSQL);
if (ordinateColData.getStatus() != 0) { //没有查询结果或出现异常
return null;
}
strSQL = "select " + abscissaCol;
for (int i = 1; i < ordinateColData.getRows(); i++) {
String ordValue = ordinateColData.getCell(0, i); //得到纵向的值
strSQL += ",sum(decode(" + ordinateCol + ",'" + ordValue + "'," +
valueCol + ",0)) as " + "A" + ordValue; //多加一个A,要不然数字不能作为列的别名
}
strSQL += " from " + tableName + " " + strWhere + " group by " +
abscissaCol;
System.out.println("生成的SQL:" + strSQL);
return dbOperate.Query(strSQL);
}
}
其中用了两个JDBC的封装类,懂JDBC的朋友一定知道怎么把他替换成自己的类的。