縱表、橫表互轉的SQL
主鍵、字段1、字段2、字段3。。。
如果變成縱表后,則表結構為:
主鍵、字段代碼、字段值。
而字段代碼則為字段1、字段2、字段3。
具體為電信行業的例子。以用戶帳單表為例一般出賬時用戶有很多費用客戶,其數據一般存儲為:時間,客戶ID,費用科目,費用。這種存儲結構一般稱為縱表,其特點是行數多,字段少。 縱表在使用時由於行數多,統計用戶數或對用戶進行分檔時還需要進行GROUP BY 操作,性能低,且操作不便,為提高性能,通常根據需要將縱表進行匯總,形成橫表,比如:時間、客戶ID,基本通話費、漫游通話費,國內長途費、國際長途費....。通常形成一個客戶一行的表,這種表統計用戶數或做分檔統計時比較方便。另外,數據挖掘時用到的寬表一般也要求是橫表結構。
縱表對從數據庫到內存的映射效率是有影響的,但細一點說也要一分為二:
縱表的初始映射要慢一些;
縱表的變更的映射可能要快一些,如果只是改變了單個字段時,畢竟橫表字段比縱表要多很多。
我想這個還是在討論如何優化數據庫數據結構的問題,而我的意見是:如果有可能,還是不要用數據庫的好,呵呵。
另:我親身遭受過帳務系統表的橫表和縱表的問題的折磨,橫表使結構一目了然,但幾乎不能擴展,當用戶部署新業務時捉襟見肘,縱表似乎有無限的擴展性,但代價是有些凌亂,不便於理解,更要命的是數據管理上不夠安全,我就知道某地方的帳務系統帳務配置表(縱表)被某位專家級操作者無意刪除了一條,就是一條啊!結果......,而橫表,你要改他的結構不是那么容易的,不過兩者對帳務程序性能的影響幾乎沒有任何區別。
縱表、橫表互轉的SQL
By:大志若愚
1、建表:
縱表結構 Table_A
create table Table_A ( 姓名 varchar(20), 課程 varchar(20), 成績 int ) insert into Table_A(姓名,課程,成績) values('張三','語文',60) insert into Table_A(姓名,課程,成績) values('張三','數學',70) insert into Table_A(姓名,課程,成績) values('張三','英語',80) insert into Table_A(姓名,課程,成績) values('李四','語文',90) insert into Table_A(姓名,課程,成績) values('李四','數學',100)
姓名 |
課程 |
成績 |
張三 |
語文 |
60 |
張三 |
數學 |
70 |
張三 |
英語 |
80 |
李四 |
語文 |
90 |
李四 |
數學 |
100 |
橫表結構 Table_B
create table Table_B ( 姓名 varchar(20), 語文 int, 數學 int, 英語 int ) insert into Table_B(姓名,語文,數學,英語) values('張三',60,70,80) insert into Table_B(姓名,語文,數學,英語) values('李四',90,100,0)
姓名 |
語文 |
數學 |
英語 |
張三 |
60 |
70 |
80 |
李四 |
90 |
100 |
0 |
2、縱表變橫表
縱表結構 Table_A --> 橫表結構 Table_B
方法一:聚合函數[max或sum]配合case語句
select 姓名, sum (case 課程 when '語文' then 成績 else 0 end) as 語文, sum (case 課程 when '數學' then 成績 else 0 end) as 數學, sum (case 課程 when '英語' then 成績 else 0 end) as 英語 from Table_A group by 姓名
方法二:使用pivot
select * from Table_A pivot (max(成績)for 課程 in(語文,數學,英語)) 臨時表
3、橫表變縱表
橫表結構 Table_B --> 縱表結構 Table_A
方法一:union all
select 姓名,'語文' as 課程,語文 as 成績 from Table_B union all select 姓名,'數學' as 課程,數學 as 成績 from Table_B union all select 姓名,'英語' as 課程,英語 as 成績 from Table_B order by 姓名,課程 desc
方法二:使用unpivot
select 姓名,課程,成績 from Table_B unpivot (成績 for 課程 in ([語文],[數學],英語)) 臨時表
說明:在實際開發中表名,列名不應該使用漢字,在插入的值中有漢字的應該用N修飾,以防止出現亂碼,出現意想不到的結果,可能產生2異性的表名可以用[]修飾。
例如:
insert into Table_B(name,chinese,math,english) values(N'張三',60,70,80)
create table [user]
---------------
2 張飛 數學 87
3 關羽 語文 97
4 張飛 英語 68
5 關羽 數學 53
6 劉備 語文 90
--用decode實現,
SELECT T.NAME,
SUM(DECODE(T.Course, '語文', T.Score)) 語文,
SUM(DECODE(T.Course, '數學', T.Score)) 數學,
SUM(DECODE(T.Course, '英語', T.Score)) 英語
FROM T_T_STUDENT T
GROUP BY T.NAME
--用case when 實現
SELECT T.NAME,
SUM(CASE T.Course WHEN '語文' THEN T.Score ELSE 0 END) 語文,
SUM(CASE T.Course WHEN '數學' THEN T.Score ELSE 0 END) 數學,
SUM(CASE T.Course WHEN '英語' THEN T.Score ELSE 0 END) 英語
FROM T_T_STUDENT T
GROUP BY T.NAME
姓名 語文 數學 英語
1 劉備 90 94 92
2 關羽 97 53 95
3 張飛 80 87 68
區別如果條件是單一值時,用decode比較簡便,如果判斷條件比較復雜是用case when實現
假設有張學生成績表(tb)如下:
Name Subject Result
張三 語文 74
張三 數學 83
張三 物理 93
李四 語文 74
李四 數學 84
李四 物理 94
*/
-------------------------------------------------------------------------
/*
想變成
姓名 語文 數學 物理
---------- ----------- ----------- -----------
李四 74 84 94
張三 74 83 93
*/
create table tb
(
Name varchar(10) ,
Subject varchar(10) ,
Result int
)
insert into tb(Name , Subject , Result) values('張三' , '語文' , 74)
insert into tb(Name , Subject , Result) values('張三' , '數學' , 83)
insert into tb(Name , Subject , Result) values('張三' , '物理' , 93)
insert into tb(Name , Subject , Result) values('李四' , '語文' , 74)
insert into tb(Name , Subject , Result) values('李四' , '數學' , 84)
insert into tb(Name , Subject , Result) values('李四' , '物理' , 94)
go
--靜態SQL,指subject只有語文、數學、物理這三門課程。
select name 姓名,
max(case subject when '語文' then result else 0 end) 語文,
max(case subject when '數學' then result else 0 end) 數學,
max(case subject when '物理' then result else 0 end) 物理
from tb
group by name
/*
姓名 語文 數學 物理
---------- ----------- ----------- -----------
李四 74 84 94
張三 74 83 93
*/
--動態SQL,指subject不止語文、數學、物理這三門課程。
declare @sql varchar(8000)
set @sql = 'select Name as ' + '姓名'
select @sql = @sql + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct Subject from tb) as a
set @sql = @sql + ' from tb group by name'
exec(@sql)
/*
姓名 數學 物理 語文
---------- ----------- ----------- -----------
李四 84 94 74
張三 83 93 74
*/
-------------------------------------------------------------------
/*加個平均分,總分
姓名 語文 數學 物理 平均分 總分
---------- ----------- ----------- ----------- -------------------- -----------
李四 74 84 94 84.00 252
張三 74 83 93 83.33 250
*/
--靜態SQL,指subject只有語文、數學、物理這三門課程。
select name 姓名,
max(case subject when '語文' then result else 0 end) 語文,
max(case subject when '數學' then result else 0 end) 數學,
max(case subject when '物理' then result else 0 end) 物理,
cast(avg(result*1.0) as decimal(18,2)) 平均分,
sum(result) 總分
from tb
group by name
/*
姓名 語文 數學 物理 平均分 總分
---------- ----------- ----------- ----------- -------------------- -----------
李四 74 84 94 84.00 252
張三 74 83 93 83.33 250
*/
--動態SQL,指subject不止語文、數學、物理這三門課程。
declare @sql1 varchar(8000)
set @sql1 = 'select Name as ' + '姓名'
select @sql1 = @sql1 + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct Subject from tb) as a
set @sql1 = @sql1 + ' , cast(avg(result*1.0) as decimal(18,2)) 平均分,sum(result) 總分 from tb group by name'
exec(@sql1)
/*
姓名 數學 物理 語文 平均分 總分
---------- ----------- ----------- ----------- -------------------- -----------
李四 84 94 74 84.00 252
張三 83 93 74 83.33 250
*/
drop table tb
---------------------------------------------------------
---------------------------------------------------------
/*
如果上述兩表互相換一下:即
姓名 語文 數學 物理
張三 74 83 93
李四 74 84 94
想變成
Name Subject Result
---------- ------- -----------
李四 語文 74
李四 數學 84
李四 物理 94
張三 語文 74
張三 數學 83
張三 物理 93
*/
create table tb1
(
姓名 varchar(10) ,
語文 int ,
數學 int ,
物理 int
)
insert into tb1(姓名 , 語文 , 數學 , 物理) values('張三',74,83,93)
insert into tb1(姓名 , 語文 , 數學 , 物理) values('李四',74,84,94)
select * from
(
select 姓名 as Name , Subject = '語文' , Result = 語文 from tb1
union all
select 姓名 as Name , Subject = '數學' , Result = 數學 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
) t
order by name , case Subject when '語文' then 1 when '數學' then 2 when '物理' then 3 when '總分' then 4 end
--------------------------------------------------------------------
/*加個平均分,總分
Name Subject Result
---------- ------- --------------------
李四 語文 74.00
李四 數學 84.00
李四 物理 94.00
李四 平均分 84.00
李四 總分 252.00
張三 語文 74.00
張三 數學 83.00
張三 物理 93.00
張三 平均分 83.33
張三 總分 250.00
*/
select * from
(
select 姓名 as Name , Subject = '語文' , Result = 語文 from tb1
union all
select 姓名 as Name , Subject = '數學' , Result = 數學 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
union all
select 姓名 as Name , Subject = '平均分' , Result = cast((語文 + 數學 + 物理)*1.0/3 as decimal(18,2)) from tb1
union all
select 姓名 as Name , Subject = '總分' , Result = 語文 + 數學 + 物理 from tb1
) t
order by name , case Subject when '語文' then 1 when '數學' then 2 when '物理' then 3 when '平均分' then 4 when'總分' then 5 end
drop table tb1
----------------新建測試表
CREATE TABLE tmp_user_2(USER_ID NUMBER,MODE_NAME VARCHAR2(100),TYPE_ID NUmBER);
----------------第一部分測試數據
INSERT INTO tmp_user_2 VALUES(1001, 'M1',1);
INSERT INTO tmp_user_2 VALUES(1001, 'M2',2);
INSERT INTO tmp_user_2 VALUES(1002, 'M1',3);
INSERT INTO tmp_user_2 VALUES(1002, 'M2',4);
INSERT INTO tmp_user_2 VALUES(1002, 'M3',5);
INSERT INTO tmp_user_2 VALUES(1003, 'M1',6);
COMMIT;
----------------行轉列存儲過程
CREATE OR REPLACE PROCEDURE P_tmp_user_2 IS
V_SQL VARCHAR2(2000);
CURSOR CURSOR_1 IS
SELECT DISTINCT T.MODE_NAME FROM tmp_user_2 T ORDER BY MODE_NAME;
BEGIN
V_SQL := 'SELECT USER_ID';
FOR V_XCLCK IN CURSOR_1 LOOP
V_SQL := V_SQL || ',' || 'SUM(DECODE(MODE_NAME,''' || V_XCLCK.MODE_NAME ||
''',TYPE_ID,0)) AS ' || V_XCLCK.MODE_NAME;
END LOOP;
V_SQL := V_SQL || ' FROM tmp_user_2 GROUP BY USER_ID';
--DBMS_OUTPUT.PUT_LINE(V_SQL);
V_SQL := 'CREATE OR REPLACE VIEW tmp_user_3 AS ' || V_SQL;
--DBMS_OUTPUT.PUT_LINE(V_SQL);
EXECUTE IMMEDIATE V_SQL;
END;
----------------執行存儲過程
BEGIN
P_tmp_user_2;
END;
----------------查看結果
SELECT * FROM tmp_user_3;
----------------第二部分測試數據
INSERT INTO tmp_user_2 VALUES(1003, 'M2',7);
INSERT INTO tmp_user_2 VALUES(1004, 'M5',8);
COMMIT;
----------------執行存儲過程
BEGIN
P_tmp_user_2;
END;
----------------查看結果
SELECT * FROM tmp_user_3;
橫表:通常指我們平時在數據庫中建立的表,是一種普通的建表方式。
(主鍵、字段1、字段2......)如:時間、客戶ID,基本通話費、漫游通話費,國內長途費、國際長途費....。
縱表:一般不多見,在表結構不確定的時候,如需增加字段的情況下的一種建表方式。
二、執行效率
橫表:后台數據庫管理員操作簡單,直觀,清晰可見,一目了然。但若要給橫表中添加一個或者多個字段,就須重建表結構。
縱表:對於橫表的弊端,縱表中只需要添加一條記錄,就可以添加一個字段,所消耗的代價遠比橫表小。但是縱表的對於數據描述不是很清晰,而且會造成數據庫數量很多。在查詢的時候用到group等函數會大大降低執行效率。縱表的初始映射要慢一些,縱表的變更的映射可能要快一些,如果只是改變了單個字段時,畢竟橫表字段比縱表要多很多。
三、轉換
1.在平時的開發過程中,可能會遇到字段的添加或者更好的維護和管理大數據量的表,就 會涉及到縱表和橫表之間的轉換。
2.把不容易改動表結構的設計成橫表,把容易經常改動不確定的表結構設計成縱表。
舉例:
注:DECODE函數是ORACLE PL/SQL的功能強大的函數之一,目前還只有ORACLE公司的SQL提供了此函數,DECODE(value,if1,then1,if2,then2,if3,then3,...,else),表示如果value等於if1時,DECODE函數的結果返回then1,...,如果不等於任何一個if值,則返回else。
sign函數:在數學和計算機運算中,其功能是取某個數的符號(正或負): 當x≥0,sign(x)=1; 當x<0, sign(x)=-1;
縱表轉橫表
- 縱表結構: TEST_Z2H
- FNAME FTYPE FVALUE
- 員工 zaocan 10
- 員工 zhongcan 20
- 員工 wancan 5
- 轉換后的表結構:
- FNAME ZAOCAN_VALUE ZHONGCAN_VALUE WANCAN_VALUE
- 員工 10 20 5
- 縱表轉橫表SQL示例:
- SELECT FNAME,
- SUM(DECODE(FTYPE,'zaocan',FVALUE,0)) AS ZAOCAN_VALUE,
- SUM(DECODE(FTYPE,'zhongcan',FVALUE,0)) AS ZHONGCAN_VALUE,
- SUM(DECODE(FTYPE,'wancan',FVALUE,0)) AS WANCAN_VALUE
- FROM TEST_Z2H
- GROUP BY FNAME;
橫表轉縱表
- 橫表結構: TEST_H2Z
- ID 姓名 語文 數學 英語
- 1 張三 80 90 70
- 2 李四 90 85 95
- 3 王五 88 75 90
- 轉換后的表結構:
- ID 姓名 科目 成績
- 1 張三 語文 80
- 2 張三 數學 90
- 3 張三 英語 70
- 4 李四 語文 90
- 5 李四 數學 80
- 6 李四 英語 99
- 7 王五 語文 85
- 8 王五 數學 96
- 9 王五 英語 88
- 橫表轉縱表SQL示例:
- SELECT 姓名,'語文' AS 科目,語文 AS 成績 FROM TEST_H2Z UNION ALL
- SELECT 姓名,'數學' AS 科目,數學 AS 成績 FROM TEST_H2Z UNION ALL
- SELECT 姓名,'英語' AS 科目,英語 AS 成績 FROM TEST_H2Z
- ORDER BY 姓名,科目 DESC;
四、這里有一篇用另一種方式實現轉換而且帶和值查詢的博文: http://exceptioneye.iteye.com/blog/1153345
橫表就是普通的建表方式,如一個表結構為:
主鍵、字段1、字段2、字段3。。。
如果變成縱表后,則表結構為:
主鍵、字段代碼、字段值。
而字段代碼則為字段1、字段2、字段3。
縱表對從數據庫到內存的映射效率是有影響的,但細一點說也要一分為二:
縱表的初始映射要慢一些;
縱表的變更的映射可能要快一些,如果只是改變了單個字段時,畢竟橫表字段比縱表要多很多。
橫表的好處是清晰可見,一目了然,但是有一個弊端,如果現在要把這個表加一個字段,那么就必須重建表結構。對於這種情況,在縱表中只需要添加一條記錄,就可以添加一個字段,所消耗的代價遠比橫表小,但是縱表的對於數據描述不是很清晰,而且會造成數據庫數量很多,兩者利弊在於此。所以,應 該把不容易改動表結構的設計成橫表,把容易經常改動不確定的表結構設計成縱表。
測試例子:
create table a(name varchar2(12),
math number,
englist number,chinese number);
插入兩行記錄:
張三 85 90 95
李四 90 85 86
轉行查詢語句:
- SELECT flag, MAX(李四) AS 李四, MAX(張三) AS 張三
- FROM (SELECT decode(NAME, '李四', fensu) as 李四,
- decode(NAME, '張三', fensu) AS 張三,
- flag
- FROM (SELECT a.NAME, a.math AS fensu, 'math' AS flag
- FROM a
- UNION ALL
- SELECT a.NAME, a.englist AS fensu, 'englist' AS flag
- FROM a
- UNION ALL
- SELECT a.NAME, a.chinese AS fensu, 'chinese' AS flag FROM a) b
- ORDER BY NAME, flag, fensu)
- GROUP BY flag
現有emp和dept表
EMP
empno number(4)
ename varchar2(10)
job varchar2(9)
mgr number(4)
hiredate date
sal number(7,2)
comm number(7,2)
deptno number(2)
DEPT
deptno number(2)
dname varchar2(14)
loc varchar2(13)
統計不同部門和工作的員工的總工資
實現橫標轉換為縱表
decode實現
- select d.dname dname,
- sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
- sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
- sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
- sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
- sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
- from emp e
- join dept d
- on e.deptno = d.deptno
- group by d.dname;
- case when實現
- select d.dname dname,
- sum(
- case e.job
- when 'CLERK' then e.sal
- else 0
- end
- ) CLERK,
- sum(
- case e.job
- when 'SALESMAN' then e.sal
- else 0
- end
- ) SALESMAN,
- sum(
- case e.job
- when 'PRESIDENT' then e.sal
- else 0
- end
- ) PRESIDENT,
- sum(
- case e.job
- when 'MANAGER' then e.sal
- else 0
- end
- ) MANAGER,
- sum(
- case e.job
- when 'ANALYST' then e.sal
- else 0
- end
- ) ANALYST
- from emp e
- join dept d
- on e.deptno = d.deptno
- group by d.dname;
- 帶合計項的
- select d.dname dname,
- sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
- sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
- sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
- sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
- sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
- from emp e
- join dept d on e.deptno = d.deptno
- group by d.dname
- union
- select '總計' dname,
- sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
- sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
- sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
- sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
- sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
- from emp e
- join dept d2 on e.deptno = d2.deptno
-----------
SQL(橫表和縱表)行列轉換,PIVOT與UNPIVOT的區別和使用方法舉例,合並列的例子
使用過SQL Server 2000的人都知道,要想實現行列轉換,必須綜合利用聚合函數和動態SQL,具體實現起來需要一定的技巧,而在SQL Server 2005中,使用新引進的關鍵字PIVOT/UNPIVOT,則可以很容易的實現行列轉換的需求。
在本文中我們將通過兩個簡單的例子詳細講解PIVOT和UNPIVOT的用法。
PIVOT是行轉列,用法如下:
假如表結構如下:
id name quarter profile
1 a 1 1000
1 a 2 2000
1 a 3 4000
1 a 4 5000
2 b 1 3000
2 b 2 3500
2 b 3 4200
2 b 4 5500
----------------------------------------------
使用PIVOT將四個季度的利潤轉換成橫向顯示:
select id,name,
[1] as "一季度",[2] as "二季度",[3] as "三季度",[4] as "四季度"
from test
pivot
(
sum(profile)
for quarter in ([1],[2],[3],[4])
)
as pvt
-----------------------------------------------
得出的結果如下:
id name 一季度 二季度 三季度 四季度
1 a 1000 2000 4000 5000
2 b 3000 3500 4200 5500
========================================================================================
UNPIVOT是列轉行,用法如下:
假如表結構如下:
id name Q1 Q2 Q3 Q4
1 a 1000 2000 4000 5000
2 b 3000 3500 4200 5500
-----------------------------------------------
使用UNPIVOT,將同一行中四個季度的列數據轉換成四行數據:
select id,name,quarter,profile
from test
unpivot
(
profile
for quarter in ([Q1],[Q2],[Q3],[Q4])
)
as unpvt
-----------------------------------------------
得出的結果如下:
id name quarter profile
1 a Q1 1000
1 a Q2 2000
1 a Q3 4000
1 a Q4 5000
2 b Q1 3000
2 b Q2 3500
2 b Q3 4200
2 b Q4 5500
------------------------------------------------------------------------------
設存在如下縱向表,第一列為id(可能是某個業務數據的id),第二列為類型,第三列為類型對應的值,如下圖:
如上表,存在2,3,4三種類型,其中業務數據ID為1的三種類型都有值,業務數據ID為2的三種類型都有值,業務數據ID為3的只有類型2和3有值,現在要把縱向表橫過來顯示,可以采用如下代碼:
- -- =========================================================
- -- 縱向表變橫向表:
- -- 1. 轉換類型,類型的值必須是整數,且不等於0,即0沒有意義,0可以表示為空
- -- =========================================================
- SELECT
- t.id,
- SUM(DECODE(t.code, 2, 2, 0)) "第二項", -- 如果該行類型為2則就是2,其它的都為0
- SUM(DECODE(t.code, 3, 3, 0)) "第三項",
- SUM(decode(t.code, 4, 4, 0)) "第四項"
- FROM ttt t WHERE t.id=1 GROUP BY t.id;
- -- =========================================================
- -- 縱向表變橫向表:
- -- 1. 轉換類型對應的數據,且數據需要是數值,且0沒有意義,即0可以表示為空
- -- =========================================================
- SELECT
- t.id,
- SUM(DECODE(t.code, 2, t.val, 0)) "第二項", -- 如果該行類型為2則顯示2類型對應的值DECODE,否則都顯示0
- SUM(DECODE(t.code, 3, t.val, 0)) "第三項",
- SUM(DECODE(t.code, 4, t.val, 0)) "第四項"
- FROM ttt t GROUP BY t.id;
----------------------------------------------------------------------------------------------------------------------------------------
oracle合並列的函數wm_concat的使用詳解
oracle wm_concat(column)函數使我們經常會使用到的,下面就教您如何使用oracle wm_concat(column)函數實現字段合並,如果您對oracle wm_concat(column)函數使用方面感興趣的話,不妨一看。
shopping:
-----------------------------------------
u_id goods num
------------------------------------------
1 蘋果 2
2 梨子 5
1 西瓜 4
3 葡萄 1
3 香蕉 1
1 橘子 3
=======================
想要的結果為:
--------------------------------
u_id goods_sum
____________________
1 蘋果,西瓜,橘子
2 梨子
3 葡萄,香蕉
---------------------------------
1.select u_id, wmsys.wm_concat(goods) goods_sum 2. 3.from shopping 4. 5.group by u_id
想要的結果2:
--------------------------------
u_id goods_sum
____________________
1 蘋果(2斤),西瓜(4斤),橘子(3斤)
2 梨子(5斤)
3 葡萄(1斤),香蕉(1斤)
---------------------------------
使用oracle wm_concat(column)函數實現:
select u_id, wmsys.wm_concat(goods || '(' || num || '斤)' ) goods_sum
from shopping
group by u_id
mysql---group_concat
SQL(橫表和縱表)行列轉換,PIVOT與UNPIVOT的區別和使用方法舉例,合並列的例子的更多相關文章
- 通過sql做數據透視表,數據庫表行列轉換(pivot和Unpivot用法)(一)
在mssql中大家都知道可以使用pivot來統計數據,實現像excel的透視表功能 一.MSsqlserver中我們通常的用法 1.Sqlserver數據庫測試 ---創建測試表 Create tab ...
- SQL Server中行列轉換 Pivot UnPivot
SQL Server中行列轉換 Pivot UnPivot PIVOT用於將列值旋轉為列名(即行轉列),在SQL Server 2000可以用聚合函數配合CASE語句實現 PIVOT的一般語法是:PI ...
- sql 行專列 列轉行 普通行列轉換
轉載:http://www.cnblogs.com/newwind521/archive/2010/11/25/1887203.html sql 行專列 列轉行 普通行列轉換 /* 標題:普通行列轉換 ...
- SQL SERVER 合並重復行,行列轉換
引用自:http://www.cnblogs.com/love-summer/archive/2012/03/27/2419778.html sql server2000 里面如何實現oracle10 ...
- SQL中行列轉換Pivot
--建表 ),課程 ),分數 int) --插入數據 ) ) ) ) ) ) 1.靜態行轉列(確定有哪些列) select 姓名, end)語文, end)數學, end)物理 from tb gro ...
- 多列的行列轉換(PIVOT,UNPIVOT)
形式1 形式2 形式3 有時候可能會有這樣的需求: 將一張表的所有列名轉做為數據的一列數據,將一列數據作為整張表的列名 當列比較多時,只用PIVOT是解決不了的,經過研究,需要將UNPIVOT 和 P ...
- 行列轉換 pivot
select * from ( select isnull(c.type,'其他') type,d from ( select ID,Record_code,code,day(thedate) d f ...
- sqlserver表分區與調優與行列轉換
轉自: http://www.cnblogs.com/knowledgesea/p/3696912.html http://www.open-open.com/lib/view/open1418462 ...
- 瑞麗的SQL-SQL Server的表旋轉(行列轉換)
所謂表旋轉,就是將表的行轉換為列,或是將表的列轉換為行,這是從SQL Server 2005開始提供的新技術.因此,如果希望使用此功能,須要將數據庫的兼容級別設置為90.表旋轉在某些方面也是攻克了表的 ...