SQL 横表和纵表的转换

2023-10-07 22:40

本文主要是介绍SQL 横表和纵表的转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

横表就是普通的建表方式,如一个表结构为:
主键、字段1、字段2、字段3。。。
如果变成纵表后,则表结构为:
主键、字段代码、字段值。
而字段代码则为字段1、字段2、字段3。

具体为电信行业的例子。以用户帐单表为例一般出账时用户有很多费用客户,其数据一般存储为:时间,客户ID,费用科目,费用。这种存储结构一般称为纵表,其特点是行数多,字段少。 纵表在使用时由于行数多,统计用户数或对用户进行分档时还需要进行GROUP BY 操作,性能低,且操作不便,为提高性能,通常根据需要将纵表进行汇总,形成横表,比如:时间、客户ID,基本通话费、漫游通话费,国内长途费、国际长途费…。通常形成一个客户一行的表,这种表统计用户数或做分档统计时比较方便。另外,数据挖掘时用到的宽表一般也要求是横表结构。

纵表对从数据库到内存的映射效率是有影响的,但细一点说也要一分为二:
纵表的初始映射要慢一些;
纵表的变更的映射可能要快一些,如果只是改变了单个字段时,毕竟横表字段比纵表要多很多。

我想这个还是在讨论如何优化数据库数据结构的问题,而我的意见是:如果有可能,还是不要用数据库的好,呵呵。
另:我亲身遭受过帐务系统表的横表和纵表的问题的折磨,横表使结构一目了然,但几乎不能扩展,当用户部署新业务时捉襟见肘,纵表似乎有无限的扩展性,但代价是有些凌乱,不便于理解,更要命的是数据管理上不够安全,我就知道某地方的帐务系统帐务配置表(纵表)被某位专家级操作者无意删除了一条,就是一条啊!结果…,而横表,你要改他的结构不是那么容易的,不过两者对帐务程序性能的影响几乎没有任何区别。

MS SQL Server

纵表、横表互转的SQL

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]


oracle SQL 实现竖表转横表

T_T_STUDENT表查询记录如下,要转成横表

      姓名     课程     成绩

1 张飞 语文 80
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(result1.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(result1.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的区别和使用方法举例,合并列的例子
牵手的承诺1 2016-10-13 原文
使用过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 testpivot(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,profilefrom testunpivot(profilefor 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


ORACLE纵向表转换为横向表写法

设存在如下纵向表,第一列为id(可能是某个业务数据的id),第二列为类型,第三列为类型对应的值,如下图:
在这里插入图片描述
如上表,存在2,3,4三种类型,其中业务数据ID为1的三种类型都有值,业务数据ID为2的三种类型都有值,业务数据ID为3的只有类型2和3有值,现在要把纵向表横过来显示,可以采用如下代码:

1.-- =========================================================
2.-- 纵向表变横向表:
3.-- 1. 转换类型,类型的值必须是整数,且不等于0,即0没有意义,0可以表示为空
4.-- =========================================================
5.SELECT
6.t.id,
7.SUM(DECODE(t.code, 2, 2, 0)) “第二项”, – 如果该行类型为2则就是2,其它的都为0
8.SUM(DECODE(t.code, 3, 3, 0)) “第三项”,
9.SUM(decode(t.code, 4, 4, 0)) “第四项”
10.FROM ttt t WHERE t.id=1 GROUP BY t.id;
11.-- =========================================================
12.-- 纵向表变横向表:
13.-- 1. 转换类型对应的数据,且数据需要是数值,且0没有意义,即0可以表示为空
14.-- =========================================================
15.SELECT
16.t.id,
17.SUM(DECODE(t.code, 2, t.val, 0)) “第二项”, – 如果该行类型为2则显示2类型对应的值DECODE,否则都显示0
18.SUM(DECODE(t.code, 3, t.val, 0)) “第三项”,
19.SUM(DECODE(t.code, 4, t.val, 0)) “第四项”
20.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 横表和纵表的转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/160908

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySql死锁怎么排查的方法实现

《MySql死锁怎么排查的方法实现》本文主要介绍了MySql死锁怎么排查的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录前言一、死锁排查方法1. 查看死锁日志方法 1:启用死锁日志输出方法 2:检查 mysql 错误

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

MySQL修改密码的四种实现方式

《MySQL修改密码的四种实现方式》文章主要介绍了如何使用命令行工具修改MySQL密码,包括使用`setpassword`命令和`mysqladmin`命令,此外,还详细描述了忘记密码时的处理方法,包... 目录mysql修改密码四种方式一、set password命令二、使用mysqladmin三、修改u