日期:2014-05-17  浏览次数:20984 次

SQL行转列问题求解,实在是想不出解决办法了,请高手们帮忙!谢谢!
如下图所示:
  年份 总人数 英国 德国 荷兰 丹麦 美国 意大利
  2009 1111 99 88 00 77 88 22
  2010 8888 11 99 00 88 33 11
  2011 8877 000 88 77 67 89 00

我想把上图转换为下图的样子:
   
  年份 2009 2010 2011
  总人数 1111 8888 8877
  英国 99 11 000
  德国 88 99 88
  荷兰 00 00 77 
  丹麦 77 88 67
  美国 88 33 89
  意大利 22 11 00
但是不知道该怎么写语句,求解!谢谢您!

------解决方案--------------------
探讨

这个 跟行转列貌似有点区别。 我没有想出。。

------解决方案--------------------
年份 总人数 英国 德国 荷兰 丹麦 美国 意大利 你这个是表头?

1.把列转成 行 来显示 (行数固定)
2.年份 用行转列 (每增加一年 增加一行)

ps:csdn贴图 很坑... ,到个人 中心 -> 我的 博客 ->写 新文章 -> 里面的编辑器 可以上传图片,然后 你在相册里面可以看到 图片了,把链接 复制过来就可以了。
------解决方案--------------------
可以看下这个
create table t1 (y number(4),c1 number(10),c2 number(10),c3 number(10),c4 number(10),c5 number(10),c6 number(10),c7 number(10));
insert into t1 values (2009,1111,99,88,00,77,88,22);
insert into t1 values (2010,8888,11,99,00,88,33,11);
insert into t1 values (2011,7766,00,88,77,67,89,00);
commit;
SELECT column_name,
SUM(y2009) y2009,
SUM(y2010) y2010,
SUM(2011) y2011
FROM
(SELECT column_name,
DECODE(y, 2009, DECODE(column_id, 2, t, 3, c1, 4, c2, 5,c3,6,c4,7,c5,8,c6),0) y2009,
DECODE(y, 2010, DECODE(column_id, 2, t, 3, c1, 4, c2, 5,c3,6,c4,7,c5,8,c6),0) y2010,
DECODE(y, 2011, DECODE(column_id, 2, t, 3, c1, 4, c2, 5,c3,6,c4,7,c5,8,c6),0) y2011
FROM user_tab_columns,
t1
WHERE table_name = 'T1'
AND column_id > 1
)
GROUP BY column_name
ORDER BY column_name;

--生成SQL语句
DECLARE
v_sum VARCHAR2(200) := 'SELECT column_name';
v_col VARCHAR2(2000);
v_tmp VARCHAR2(200);
v_sql VARCHAR2(4000);
BEGIN
FOR rc IN(SELECT DISTINCT y FROM t1)
LOOP
v_sum := v_sum || ', SUM(y' || rc.y || ') y' || rc.y;
v_col := v_col || ', DECODE(y, ' || rc.y || ', DECODE(column_id ';
FOR col IN(SELECT column_name,column_id FROM user_tab_columns
WHERE column_id > 1 AND table_name = 'T1')
LOOP
v_tmp := v_tmp || ',' || col.column_id || ',' || col.column_name;
END LOOP;
v_col := v_col || v_tmp || '), 0)' || ' y' || rc.y;
v_tmp := NULL;
END LOOP;
v_sql := v_sum || ' FROM (SELECT column_name ' || v_col
|| ' FROM user_tab_columns, t1 WHERE column_id > 1 ' 
|| 'and table_name = ''T1'') GROUP BY column_name ORDER BY column_name';
dbms_output.put_line(v_sql);
END;
------解决方案--------------------
SQL code

--如果数据量太大的话这个代码量会很大,但是一时想不出其他的办法,因为你的列名要做为行的内容,只有硬编码。--
WITH t1 AS (
SELECT 2009 YEAR,1111 TOTAL_PEO,99 US,88 GER,0 NL,77 DEN FROM DUAL
UNION ALL
SELECT 2010, 8888, 11 ,99, 0, 88 FROM DUAL
UNION ALL
SELECT 2011, 8877, 0, 88, 77, 67 FROM DUAL
)
SELECT 'YEAR' C_NUM_Y, 2009 C_NUM_Y_09,2010 C_NUM_Y_10,2011 C_NUM_Y_11 FROM dual
UNION ALL
SELECT 'TOTAL_PEO',MAX(DECODE(t1.YEAR,2009,t1.TOTAL_PEO)),MAX(DECODE(t1.YEAR,2010,t1.TOTAL_PEO)),MAX(DECODE(t1.YEAR,2011,t1.TOTAL_PEO)) FROM t1
UNION ALL 
SELECT 'US',MAX(DECODE(t1.YEAR,2009,t1.US)),MAX(DECODE(t1.YEAR,2010,t1.US)),MAX(DECODE(t1.YEAR,2011,t1.US)) FROM t1
UNION ALL 
SELECT 'GER',MAX(DECODE(t1.YEAR,2009,t1.GER)),MAX(DECODE(t1.YEAR,2010,t1.GER)),MAX(DECODE(t1.YEAR,2011,t1.GER)) FROM t1
UNION ALL 
SELECT 'NL',MAX(DECODE(t1.YEAR,2009,t1.NL)),MAX(DECODE(t1.YEAR,2010,t1.NL)),MAX(D