SQL Server 如何将 a,b,c,d行模式变成一列(只有一行)?只有20分全部捐出来了。谢谢 a b c d

问题是,一行4列变成1列4行,除了union还有什么好办法么

总结一下关于行列转置的实现方法1、固定列数的行列转换如student subject grade--------- ---------- --------student1 语文 80student1 数学 70student1 英语 60student2 语文 90student2 数学 80student2 英语 100……转换为语文 数学 英语student1 80 70 60student2 90 80 100……语句如下:select student, sum(decode(subject,'语文', grade,null)) "语文",sum(decode(subject,'数学', grade,null)) "数学",sum(decode(subject,'英语', grade,null)) "英语"from tablegroup by student; 
2、不定列行列转换如c1 c2--- -----------1 我1 是1 谁2 知2 道3 不……转换为1 我是谁2 知道3 不
这一类型的转换可以借助于PL/SQL来完成,这里给一个例子CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)RETURN VARCHAR2ISCol_c2 VARCHAR2(4000);BEGINFOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOPCol_c2 := Col_c2||cur.c2;END LOOP;Col_c2 := rtrim(Col_c2,1);RETURN Col_c2;END;
select distinct c1 ,get_c2(c1) cc2 from table;
或者不用pl/sql,利用分析函数和 CONNECT_BY 实现:
SELECT c1, SUBSTR (MAX (SYS_CONNECT_BY_PATH (c2, ';')), 2) NAME FROM (SELECT c1, c2, rn, LEAD (rn) OVER (PARTITION BY c1 ORDER BY rn) rn1 FROM (SELECT c1, c2, ROW_NUMBER () OVER (ORDER BY c2) rn FROM t))START WITH rn1 IS NULLCONNECT BY rn1 = PRIOR rnGROUP BY c1;
3、列数不固定(交叉表行列转置)这种是比较麻烦的一种,需要借助pl/sql:
原始数据:CLASS1 CALLDATE CALLCOUNT1 2005-08-08 401 2005-08-07 62 2005-08-08 773 2005-08-09 333 2005-08-08 93 2005-08-07 21
转置后:CALLDATE CallCount1 CallCount2 CallCount3------------ ---------- ---------- ----------2005-08-09 0 0 332005-08-08 40 77 92005-08-07  6      0 21
试验如下:1). 建立测试表和数据CREATE TABLE t( class1 VARCHAR2(2 BYTE), calldate DATE, callcount INTEGER);
INSERT INTO t(class1, calldate, callcount)VALUES ('1', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 40);
INSERT INTO t(class1, calldate, callcount)VALUES ('1', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 6);
INSERT INTO t(class1, calldate, callcount)VALUES ('2', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 77);
INSERT INTO t(class1, calldate, callcount)VALUES ('3', TO_DATE ('08/09/2005', 'MM/DD/YYYY'), 33);
INSERT INTO t(class1, calldate, callcount)VALUES ('3', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 9);
INSERT INTO t(class1, calldate, callcount)VALUES ('3', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 21);
COMMIT ;
2). 建立ref cursor准备输出结果集 CREATE OR REPLACE PACKAGE pkg_getrecordIS TYPE myrctype IS REF CURSOR;END pkg_getrecord;/
3). 建立动态sql交叉表函数,输出结果集 CREATE OR REPLACE FUNCTION fn_rs RETURN pkg_getrecord.myrctypeIS s VARCHAR2 (4000); CURSOR c1 IS SELECT ',sum(case when Class1=' || class1 || ' then CallCount else 0 end)' || ' "CallCount' || class1 || '"' c2 FROM t GROUP BY class1; r1 c1%ROWTYPE; list_cursor pkg_getrecord.myrctype;BEGIN s := 'select CallDate '; OPEN c1; LOOP FETCH c1 INTO r1; EXIT WHEN c1%NOTFOUND; s := s || r1.c2; END LOOP; CLOSE c1; s := s || ' from T group by CallDate order by CallDate desc '; OPEN list_cursor FOR s; RETURN list_cursor;END fn_rs;/
4). 测试在sql plus下执行:var results refcursor;exec :results := fn_rs;print results;CALLDATE CallCount1 CallCount2 CallCount3--------------- ---------- ---------- ----------2005-08-09 0 0 332005-08-08 40 77 92005-08-07 6 0 21

参见:http://www.itpub.net/thread-293596-2-1.html
此贴很好,建议楼主细细品读
温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-06-28
1. 旧的解决方法
-- 1. 创建处理函数CREATE FUNCTION dbo.f_str(@id int)RETURNS varchar(8000)ASBEGIN DECLARE @r varchar(8000) SET @r = '' SELECT @r = @r + ',' + value FROM tb WHERE id=@id RETURN STUFF(@r, 1, 1, '')ENDGO-- 调用函数
SELECt id, values=dbo.f_str(id) FROM tb GROUP BY id
-- 2. 新的解决方法(适用于2005及以后版本)-- 示例数据DECLARE @t TABLE(id int, value varchar(10))INSERT @t SELECT 1, 'aa'UNION ALL SELECT 1, 'bb'UNION ALL SELECT 2, 'aaa'UNION ALL SELECT 2, 'bbb'UNION ALL SELECT 2, 'ccc'
-- 查询处理SELECT *FROM( SELECT DISTINCT id FROM @t)AOUTER APPLY( SELECT [values]= STUFF(REPLACE(REPLACE( ( SELECT value FROM @t N WHERE id = A.id FOR XML AUTO ), '<N value="', ','), '"/>', ''), 1, 1, ''))N本回答被提问者和网友采纳
第2个回答  2012-06-28
有没有样表,上图说明问题.不知道你说的是不是
本来有ABCD四列,要变成 E 列 ,E列的值包含ABCD四列的.追问

是的

相似回答
大家正在搜