数据库表行转列
- 格式:doc
- 大小:31.50 KB
- 文档页数:3
sqlserver⾏转列及列转⾏的使⽤在我们使⽤的数据库表中经常需要⽤到⾏列互相转换的情况,使⽤sql 的关键词 UNPIVOT(列转⾏)和PIVOT(⾏转列)可轻松实现⾏列转换。
⼀、列转⾏:员⼯⽉份排班表存储是采⽤1号~31号作为列的⽅式进⾏存储的现通过 UNPIVOT 将每天的班次⽤⾏进⾏展⽰,sql 如下:SELECT distinct t.Pb_Job_No,t.Year_Month ,convert(int, REPLACE( t.day,'day','')) as day,classno FROM Scheduling_InfoUNPIVOT(classno FOR day IN(Day1,Day2,Day3,Day4,Day5,Day6,Day7 ,Day8 ,Day9,Day10,Day11,Day12,Day13,Day14,Day15,Day16,Day17,Day18,Day19,Day20,Day21,Day22,Day23,Day24,Day25,Day26,Day27,Day28,Day29,Day30,Day31)) Twhere Year_Month='2020-05'and Pb_Job_No='0997'order by Pb_Job_No,day这⾥的关键词是UNPIVOT(classno FOR day IN('⽇期列名') ,其中 ‘day’是存储⽇期的列,classno 是存储原有班次的列查询结果如下:⼆、⾏转列:如果将上述列转⾏查询的结果表定义为 Scheduling_DayInfo,进⾏逆转为原始表,那么sql 语句为:SELECT Pb_Job_No,[1],[2] ,[3] ,[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31]fromScheduling_DayInfo PIVOT ( max(classno) FOR[day]IN([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31]) )t结果为:此处的 in 必须是列 day 中的值,使⽤pivot 需要⽤到聚合函数(sum,count,avg,max,min 等),使⽤的场景如考试成绩 sum(score) ,年度销售业绩等,由于此处不需要统计但是⼜必须⽤聚合函数,所以使⽤max 凑合,因为这些函数可以接受字符类型的参数。
oracle的行转列函数Oracle是一种现代化、高效的数据库管理系统,它在行列转换方面有着强大的转换函数和工具。
行列转换函数是Oracle数据库中的一个重要组成部分,它可以用来将行数据转换为列数据,或将列数据转换为行数据,这在业务分析、数据挖掘等方面都有着极大的用处。
本文将简要介绍Oracle中的行列转换函数。
1. UNPIVOT函数UNPIVOT函数可以将一张带有多个列的表,转换为只有两列的表,其中一列是原来表格的列名,另一列是原来表格这一列的值。
UNPIVOT函数的语法如下:```SELECT *FROM table_name UNPIVOT((value1, 'column1') FOR column1 IN (column2, column3, ...),(value2, 'column2') FOR column2 IN (column3, column4, ...),...);```其中,table_name代表要转换的表格的名称,columnX代表原表格中的列名,valueX代表原表格中的值。
例如,若原表格中有A、B、C、D四个列,包含多行数据,那么可以使用以下语句将其转换为只有两列的表:该语句将生成两列,一列为name,包含了A、B、C、D四个列的名称,另一列为value,包含了相应列的值。
这样就可以方便地进行数据分析了。
该语句将生成一列key,表示原表格中的唯一关键字列,另外还有A、B、C三列,表示原表格中包含的三个列,每行记录表示一个唯一的key值和对应的A、B、C三个列的值。
3. CROSS JOIN函数CROSS JOIN函数可以将两个表中的每一个记录都做一个笛卡尔积,生成一个新表。
例如,若有两个表T1和T2,T1有列A、B,T2有列C、D,可以使用以下语句将它们进行笛卡尔积,生成一个新表:```SELECT *FROM T1CROSS JOIN T2;```该语句将生成一个新表,包含了所有T1和T2中的记录的笛卡尔积。
1、列转行CREA TE TABLE t_col_row(ID INT,c1 V ARCHAR2(10),c2 V ARCHAR2(10),c3 V ARCHAR2(10));INSERT INTO t_col_row V ALUES (1, 'v11', 'v21', 'v31'); INSERT INTO t_col_row V ALUES (2, 'v12', 'v22', NULL); INSERT INTO t_col_row V ALUES (3, 'v13', NULL, 'v33'); INSERT INTO t_col_row V ALUES (4, NULL, 'v24', 'v34'); INSERT INTO t_col_row V ALUES (5, 'v15', NULL, NULL); INSERT INTO t_col_row V ALUES (6, NULL, NULL, 'v35'); INSERT INTO t_col_row V ALUES (7, NULL, NULL, NULL); COMMIT;SELECT * FROM t_col_row;1)UNION ALL适用范围:8i,9i,10g及以后版本SELECT id, 'c1' cn, c1 cvFROM t_col_rowUNION ALLSELECT id, 'c2' cn, c2 cvFROM t_col_rowUNION ALLSELECT id, 'c3' cn, c3 cv FROM t_col_row;若空行不需要转换,只需加一个where条件,WHERE COLUMN IS NOT NULL 即可。
mysql行转列常用函数
MySQL行转列是在数据库中的一种常用操作,它可以将多行数据转换为多列,以满足不同用户的需求。
MySQL提供了许多用于行转列的函数,可以帮助用户轻松地完成行转列操作。
首先,MySQL中提供了GROUP_CONCAT函数,它可以将多行数据合并成一行,用逗号分隔,以便将多行数据转换为多列。
GROUP_CONCAT函数的使用方法如下:SELECT GROUP_CONCAT(column_name) FROM table_name;
其次,MySQL中还提供了PIVOT函数,PIVOT函数可以把一张表中的行转换为列,可以为表中的行提供一个列作为分类的依据,从而实现对数据的转换。
PIVOT函数的使用方法如下:SELECT * FROM PIVOT (SUM(column_name) FOR row_name IN (row_values));
最后,MySQL中还提供了UNPIVOT函数,它可以将一个表中的多列转换为多行,使用UNPIVOT函数可以将原本分散在多列中的数据,合并到同一行中,从而实现行转列的功能。
UNPIVOT函数的使用方法如下:SELECT * FROM UNPIVOT(column_name FOR row_name IN (row_values));
总之,MySQL提供了许多用于行转列的函数,包括GROUP_CONCAT函数、PIVOT函数、UNPIVOT函数等,使用这些
函数可以轻松地将行转换为列,或将列转换为行,从而满足用户不同的需求。
oracle的行转列函数Oracle的行转列函数是指将一些列的多个行值转换为一行,通常用于将多行数据合并成单行数据,以便于进行数据汇总或者分析。
在Oracle中,行转列的主要方法有使用PIVOT和UNPIVOT函数以及使用CASE语句进行条件判断。
1.使用PIVOT函数PIVOT函数用于将行数据转换为列数据。
它的语法如下:PIVOT聚合函数FOR列名IN('列值1'AS'新列名1','列值2'AS'新列名2',...);例如,假设有一个表student,包含了姓名(name)、课程(course)和分数(score)三个字段,如下所示:name course score-----------------------Alice Math 85Alice Chinese 90Alice English 95Bob Math 80Bob Chinese 75Bob English 85现在我们希望将每个学生的课程及其对应的分数转换为一行数据,可以使用如下的PIVOT语句:SELECT*FROMSELECT name, course, scoreFROM studentPIVOTAVG(score) -- 可以是其他聚合函数,如SUM、MAX等FOR courseIN ('Math' AS Math, 'Chinese' AS Chinese, 'English' AS English);执行该查询后,将得到如下的结果:name Math Chinese English-------------------------------Alice 85 90 95Bob 80 75 852.使用UNPIVOT函数UNPIVOT函数是PIVOT函数的逆操作,用于将列数据转换为行数据。
它的语法如下:UNPIVOT转换列名FOR列名IN(新列名1AS'列值1',新列名2AS'列值2',...);例如,假设有一个表student,包含了姓名(name)、Math、Chinese 和English三个科目的分数,我们希望将这三个科目的分数转换为一列数据,可以使用如下的UNPIVOT语句:SELECT*FROMSELECT name, Math, Chinese, EnglishFROM studentUNPIVOTscoreFOR courseIN (Math AS 'Math', Chinese AS 'Chinese', English AS'English');执行该查询后,将得到如下的结果:name course score---------------------Alice Math 85Alice Chinese 90Alice English 95Bob Math 80Bob Chinese 75Bob English 853.使用CASE语句进行条件判断除了使用PIVOT和UNPIVOT函数外,我们还可以使用CASE语句进行条件判断,实现行转列的功能。
mysql行转列的方法MySQL是一种常用的关系型数据库管理系统,它提供了丰富的功能和灵活的查询语言,可以方便地操作和管理数据。
在实际的数据库应用中,有时我们需要将行数据转换为列数据,以满足特定的需求。
本文将介绍一些常见的MySQL行转列的方法。
一、使用CASE语句实现行转列CASE语句是MySQL中用于实现条件判断的语句,在行转列中也可以发挥作用。
假设我们有一个学生成绩表,包含学生ID、科目和成绩三个字段,现在需要将每个学生的各科成绩转换为列数据,可以使用以下的SQL语句:```sqlSELECT学生ID,MAX(CASE WHEN 科目 = '数学' THEN 成绩 END) AS 数学,MAX(CASE WHEN 科目 = '语文' THEN 成绩 END) AS 语文,MAX(CASE WHEN 科目 = '英语' THEN 成绩 END) AS 英语FROM成绩表GROUP BY学生ID;以上SQL语句中,我们通过在SELECT子句中使用CASE语句,根据科目的不同将成绩转换为不同的列。
通过使用MAX函数,可以将每个学生的各科成绩放到对应的列中,如果某个学生没有某科目的成绩,则对应的列值为NULL。
二、使用GROUP_CONCAT函数实现行转列GROUP_CONCAT函数是MySQL中用于将多行数据合并为一行的函数,在行转列中也可以派上用场。
假设我们有一个订单表,包含订单ID、产品名称和数量三个字段,现在需要将每个订单的产品名称和数量以逗号分隔的形式转换为列数据,可以使用以下的SQL语句:```sqlSELECT订单ID,GROUP_CONCAT(产品名称) AS 产品列表,GROUP_CONCAT(数量) AS 数量列表FROM订单表GROUP BY订单ID;以上SQL语句中,我们通过在SELECT子句中使用GROUP_CONCAT函数,将每个订单的产品名称和数量合并为一个字符串,并以逗号分隔。
mssql数据库表⾏转列,列转⾏⽐较经典--⾏列互转/****************************************************************************************************************************************************** 以学⽣成绩为例⼦,⽐较形象易懂整理⼈:中国风(Roy)⽇期:2008.06.06******************************************************************************************************************************************************/ --1、⾏互列--> --> (Roy)⽣成測試數據if not object_id('Class') is nulldrop table ClassGoCreate table Class([Student] nvarchar(2),[Course] nvarchar(2),[Score] int)Insert Classselect N'张三',N'语⽂',78 union allselect N'张三',N'数学',87 union allselect N'张三',N'英语',82 union allselect N'张三',N'物理',90 union allselect N'李四',N'语⽂',65 union allselect N'李四',N'数学',77 union allselect N'李四',N'英语',65 union allselect N'李四',N'物理',85Go--2000⽅法:动态:declare @s nvarchar(4000)set @s=''Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+' then [Score] else 0 end)'from Class group by[Course]exec('select [Student]'+@s+' from Class group by [Student]')⽣成静态:select[Student],[数学]=max(case when [Course]='数学' then [Score] else 0 end),[物理]=max(case when [Course]='物理' then [Score] else 0 end),[英语]=max(case when [Course]='英语' then [Score] else 0 end),[语⽂]=max(case when [Course]='语⽂' then [Score] else 0 end)fromClassgroup by [Student]GO动态:declare @s nvarchar(4000)Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]exec('select * from Class pivot (max([Score]) for [Course] in('+@s+'))b')⽣成静态:select *fromClasspivot(max([Score]) for [Course] in([数学],[物理],[英语],[语⽂]))b⽣成格式:/*Student 数学物理英语语⽂------- ----------- ----------- ----------- -----------李四 77 85 65 65张三 87 90 82 78(2 ⾏受影响)*/------------------------------------------------------------------------------------------go--加上总成绩(学科平均分)--2000⽅法:动态:declare @s nvarchar(4000)set @s=''Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+' then [Score] else 0 end)' from Class group by[Course]exec('select [Student]'+@s+',[总成绩]=sum([Score]) from Class group by [Student]')--加多⼀列(学科平均分⽤avg([Score])) ⽣成动态:select[Student],[数学]=max(case when [Course]='数学' then [Score] else 0 end),[物理]=max(case when [Course]='物理' then [Score] else 0 end),[英语]=max(case when [Course]='英语' then [Score] else 0 end),[语⽂]=max(case when [Course]='语⽂' then [Score] else 0 end),[总成绩]=sum([Score]) --加多⼀列(学科平均分⽤avg([Score]))fromClassgroup by [Student]go--2005⽅法:动态:declare @s nvarchar(4000)Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course] --isnull(@s+',','') 去掉字符串@s中第⼀个逗号exec('select [Student],'+@s+',[总成绩] from (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) apivot (max([Score]) for [Course] in('+@s+'))b ')⽣成静态:select[Student],[数学],[物理],[英语],[语⽂],[总成绩]from(select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a --平均分时⽤avg([Score])pivot(max([Score]) for [Course] in([数学],[物理],[英语],[语⽂]))b⽣成格式:/*Student 数学物理英语语⽂总成绩------- ----------- ----------- ----------- ----------- -----------李四 77 85 65 65 292张三 87 90 82 78 337(2 ⾏受影响)*/go--2、列转⾏--> --> (Roy)⽣成測試數據if not object_id('Class') is nulldrop table ClassGoCreate table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语⽂] int)Insert Classselect N'李四',77,85,65,65 union allselect N'张三',87,90,82,78Go--2000:动态:declare @s nvarchar(4000)select @s=isnull(@s+' union all ','')+'select [Student],[Course]='+quotename(Name,'''')--isnull(@s+' union all ','') 去掉字符串@s中第⼀个union all+',[Score]='+quotename(Name)+' from Class'from syscolumns where ID=object_id('Class') and Name not in('Student')--排除不转换的列order by Colidexec('select * from ('+@s+')t order by [Student],[Course]')--增加⼀个排序⽣成静态:select *from (select [Student],[Course]='数学',[Score]=[数学] from Class union allselect [Student],[Course]='物理',[Score]=[物理] from Class union allselect [Student],[Course]='英语',[Score]=[英语] from Class union allselect [Student],[Course]='语⽂',[Score]=[语⽂] from Class)torder by [Student],[Course]go--2005:动态:declare @s nvarchar(4000)select @s=isnull(@s+',','')+quotename(Name)from syscolumns where ID=object_id('Class') and Name not in('Student')order by Colidexec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')goselectStudent,[Course],[Score]fromClassunpivot([Score] for [Course] in([数学],[物理],[英语],[语⽂]))b⽣成格式:/*Student Course Score------- ------- -----------李四数学 77李四物理 85李四英语 65李四语⽂ 65张三数学 87张三物理 90张三英语 82张三语⽂ 78(8 ⾏受影响)*/===========================(例⼆)===================================--⾏转列问题--建⽴測試環境Create Table TEST(DATES Varchar(6),EMPNO Varchar(5),STYPE Varchar(1),AMOUNT Int)--插⼊數據Insert TEST Select '200605', '02436', 'A', 5Union All Select '200605', '02436', 'B', 3Union All Select '200605', '02436', 'C', 3Union All Select '200605', '02436', 'D', 2Union All Select '200605', '02436', 'E', 9Union All Select '200605', '02436', 'F', 7Union All Select '200605', '02436', 'G', 6Union All Select '200605', '02438', 'A', 7Union All Select '200605', '02438', 'B', 8Union All Select '200605', '02438', 'C', 0Union All Select '200605', '02438', 'D', 3Union All Select '200605', '02438', 'E', 4Union All Select '200605', '02438', 'F', 5Union All Select '200605', '02438', 'G', 1GO--測試--如果STYPE固定,可以這麼寫SelectDATES,EMPNO,SUM(Case STYPE When 'A' Then AMOUNT Else 0 End) As A,SUM(Case STYPE When 'B' Then AMOUNT Else 0 End) As B,SUM(Case STYPE When 'C' Then AMOUNT Else 0 End) As C,SUM(Case STYPE When 'D' Then AMOUNT Else 0 End) As D,SUM(Case STYPE When 'E' Then AMOUNT Else 0 End) As E,SUM(Case STYPE When 'F' Then AMOUNT Else 0 End) As F,SUM(Case STYPE When 'G' Then AMOUNT Else 0 End) As GFrom TESTGroup By DATES,EMPNOOrder By DATES,EMPNO--如果STYPE不固定,⽤動態語句Declare @S Varchar(1000)Set @S=''Select @S=@S+',SUM(Case STYPE When '''+STYPE+''' Then AMOUNT Else 0 End) As '+STYPE From (Select Distinct STYPE From TEST) A Order By STYPESet @S='Select DATES,EMPNO'+@S+' From TEST Group By DATES,EMPNO Order By DATES,EMPNO'EXEC(@S)GO--如果被转置的是数字类型的话,应⽤下列语句DECLARE @S VARCHAR(1000)SET @S='SELECT DATES,EMPNO 'SELECT @S=@S+',['+STYPE+']=SUM(CASE WHEN STYPE='''+STYPE+''' THEN AMOUNT ELSE 0 END)'FROM (Select Distinct STYPE From TEST) A Order By STYPESET @S=@S+' FROM TEST GROUP BY DATES,EMPNO'EXEC(@S)如果是列转⾏的话直接Union All就可以了例如:city style color 46 48 50 52长沙 S6MF01002 152 1 2 2 1长沙 S6MF01002 201 1 2 2 1上⾯到下⾯的样⼦city style color size qty长沙 S6MF01002 152 46 1长沙 S6MF01002 152 48 2长沙 S6MF01002 152 50 2长沙 S6MF01002 152 52 1长沙 S6MF01002 201 46 1长沙 S6MF01002 201 48 2长沙 S6MF01002 201 50 2长沙 S6MF01002 201 52 1Select City,Style,Color,[46] From TestUnion allSelect City,Style,Color,[48] From TestUnion allSelect City,Style,Color,[50] From TestUnion allSelect City,Style,Color,[52] From Test就可以了===========================(例三)===============================CREATE TABLE tb (GroupName VARCHAR(64),Price decimal(10,2))INSERT INTO tbSELECT 'VIP客户',1011.00UNION ALLSELECT'⽩⾦卡会员',225.00UNION ALLSELECT'⽩⾦卡会员1',225.00UNION ALLSELECT'⽩⾦卡会员2',225.00UNION ALLSELECT'⽩⾦卡会员3',225.00UNION ALLSELECT'⽩⾦卡会员4',225.00UNION ALLSELECT'⽩⾦卡会员4',225.00--DROP TABLE tbdeclare @s nvarchar(max)set @s=''Select @s=@s+','+quotename(GroupName)+'=max(case when [GroupName]='+quotename(GroupName,'''')+' then [price] else 0 end)' from tb group by GroupNameSELECT @s=SUBSTRING(@s,2,LEN(@s))EXEC ('select '+@s+' from tb ')/*VIP客户⽩⾦卡会员⽩⾦卡会员1 ⽩⾦卡会员2 ⽩⾦卡会员3 ⽩⾦卡会员4--------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------1011.00 225.00 225.00 225.00 225.00 225.00(1 ⾏受影响)*/。
sql行转列的几种方法SQL语言中,行转列是一种常见的数据转换操作,用于将行数据转换为列数据,以便更方便地进行数据分析和统计。
在实际的数据处理中,行转列操作有多种方法可以实现,本文将介绍其中的几种常用方法。
一、使用CASE语句CASE语句是SQL语言中的条件表达式,可以根据条件返回不同的结果。
在行转列操作中,可以使用CASE语句将多个行数据转换为对应的列数据。
例如,有一个表格包含了员工的姓名和所属部门信息,现在要将部门信息转换为列数据,可以使用如下的SQL语句:```SELECT姓名,CASE WHEN 部门 = '部门A' THEN '是' ELSE '否' END AS 部门A,CASE WHEN 部门 = '部门B' THEN '是' ELSE '否' END AS 部门B,CASE WHEN 部门 = '部门C' THEN '是' ELSE '否' END AS 部门CFROM员工表;```上述SQL语句将根据不同的部门信息,将结果集中的部门列转换为对应的列数据,输出每个员工所属部门的信息。
二、使用PIVOT函数PIVOT函数是一种高级的行转列操作方法,在某些数据库中支持。
该函数可以将行数据转换为列数据,并实现数据的聚合操作。
例如,有一个表格包含了销售人员的姓名、所属部门和销售额信息,现在要将销售额按照部门进行汇总,并将部门数据转换为列数据,可以使用如下的SQL语句:```SELECT姓名,[部门A] AS 部门A销售额,[部门B] AS 部门B销售额,[部门C] AS 部门C销售额FROM(SELECT姓名,部门,销售额FROM销售表) AS 原始数据PIVOT(SUM(销售额)FOR 部门 IN ([部门A], [部门B], [部门C])) AS 转换后的数据;```上述SQL语句中,使用了PIVOT函数将原始数据按照部门进行汇总,并将部门数据转换为列数据,输出每个销售人员在不同部门的销售额信息。
db2 行转列函数
db2行转列函数是一种广泛应用于IBMDB2数据库的特殊处理方式,它的主要作用是实现数据行的转换,以满足不同应用程序中的需求。
db2行转列函数是一种可以将查询结果中的行变成列的处理方式,它可以有效地将多行记录转换成多列记录。
这类函数通常可以被视为内部SQL函数,并可以使用SQL代码来实现行转列操作。
执行行转列函数以后,查询结果会根据函数指定的列转换为行,从而新增一些列。
例如,我们可以通过db2行转列函数实现一种数据库报表,这种报表可以被视为一个标准的表格,表格中的每一行代表一种属性,列中的每一列代表该属性的不同值。
使用行转列函数,可以把表格中的每一列转换成行形式,以获得更清晰、有用的报表。
此外,db2行转列函数还可以用于实现特定的数据处理功能。
例如,如果需要统计一个时间段内的订单数量,可以使用行转列函数,将每一天的订单数量转换成列,为统计做准备。
除此之外,还可以使用行转列函数处理多行记录,利用执行后的结果,进行统计分析或者其他操作。
db2行转列函数可以极大地提高数据处理的效率,在一些数据处理应用中,这种函数可以帮助开发者更方便地实现一些复杂的数据处理操作。
但是,由于db2行转列函数有些性能问题,在大规模的数据处理应用中,它仍然需要进行优化,以获得更好的执行效率。
综上所述,db2行转列函数是一种广泛使用的处理方式,它可以
有效地实现行转列的操作,尤其是在实现一些复杂的数据处理操作时,采用它可以有效地提高处理效率。
然而,由于这类函数存在一些性能问题,因此需要通过行转列函数的优化来改善执行效率,以满足使用者的需要。
psql行转列的方法在PostgreSQL中,行转列是将一行数据转换为列的数据。
这种转换通常使用crosstab函数来实现。
但在使用crosstab函数之前,我们首先需要安装“tablefunc”扩展。
以下是行转列的方法:1. 安装“tablefunc”扩展要使用crosstab函数,我们需要先安装“tablefunc”扩展。
在PostgreSQL命令行中执行以下命令来安装该扩展:```sqlCREATE EXTENSION tablefunc;```2.创建数据库表格为了演示行转列的过程,我们首先需要创建一个包含原始数据的数据库表格。
假设我们有一个名为“sales”的表格,包含以下列:date、product、quantity。
```sqlCREATE TABLE salesdate date,product text,quantity integer```插入一些示例数据:```sqlINSERT INTO sales (date, product, quantity) VALUES('2024-01-01','A',10),('2024-01-02','A',8),('2024-01-01','B',5),('2024-01-02','B',3);```3. 使用crosstab进行行转列使用crosstab函数进行行转列操作。
crosstab函数接受三个参数:第一个参数是转换的查询结果,第二个参数是纵向的列,第三个参数是横向的列。
```sqlSELECT * FROM crosstab'SELECT date, product, quantityFROM salesORDERBY1,2','SELECT DISTINCT productFROM salesORDERBY1'ASdate date,product1 integer,product2 integer```这将返回以下结果:date , product1 , product2------------,----------,----------2024-01-01,10,52024-01-02,8,3在这个例子中,我们将“product”列转换为两列(product1和product2),并将每个日期的数量填充到相应的列中。
数据库表行转列,列转行终极方案
转自:/liangpei2008/archive/2006/07/08/893945.aspx --行转列问题
--建立測試環境
Create Table TEST
(DATES Varchar(6),
EMPNO Varchar(5),
STYPE Varchar(1),
AMOUNT Int)
--插入數據
Insert TEST Select '200605', '02436', 'A', 5
Union All Select '200605', '02436', 'B', 3
Union All Select '200605', '02436', 'C', 3
Union All Select '200605', '02436', 'D', 2
Union All Select '200605', '02436', 'E', 9
Union All Select '200605', '02436', 'F', 7
Union All Select '200605', '02436', 'G', 6
Union All Select '200605', '02438', 'A', 7
Union All Select '200605', '02438', 'B', 8
Union All Select '200605', '02438', 'C', 0
Union All Select '200605', '02438', 'D', 3
Union All Select '200605', '02438', 'E', 4
Union All Select '200605', '02438', 'F', 5
Union All Select '200605', '02438', 'G', 1
GO
--測試
--如果STYPE固定,可以這麼寫
Select
DATES,
EMPNO,
SUM(Case STYPE When 'A' Then AMOUNT Else 0 End) As A,
SUM(Case STYPE When 'B' Then AMOUNT Else 0 End) As B,
SUM(Case STYPE When 'C' Then AMOUNT Else 0 End) As C,
SUM(Case STYPE When 'D' Then AMOUNT Else 0 End) As D,
SUM(Case STYPE When 'E' Then AMOUNT Else 0 End) As E,
SUM(Case STYPE When 'F' Then AMOUNT Else 0 End) As F,
SUM(Case STYPE When 'G' Then AMOUNT Else 0 End) As G
From TEST
Group By DATES,EMPNO
Order By DATES,EMPNO
--如果STYPE不固定,用動態語句
Declare @S Varchar(1000)
Set @S=''
Select @S=@S+',SUM(Case STYPE When '''+STYPE+''' Then AMOUNT Else 0 End) As '+STYPE From (Select Distinct STYPE From TEST) A Order By STYPE
Set @S='Select DATES,EMPNO'+@S+' From TEST Group By DATES,EMPNO Order By DATES,EMPNO'
EXEC(@S)
GO
--如果被转置的是数字类型的话,应用下列语句
DECLARE @S VARCHAR(1000)
SET @S='SELECT DATES,EMPNO '
SELECT @S=@S+',['+STYPE+']=SUM(CASE WHEN STYPE='''+STYPE+''' THEN AMOUNT ELSE 0 END)'
FROM (Select Distinct STYPE From TEST) A Order By STYPE
SET @S=@S+' FROM TEST GROUP BY DATES,EMPNO'
EXEC(@S)
如果是列转行的话直接Union All就可以了
例如:
city style color 46 48 50 52
长沙S6MF01002 152 1 2 2 1
长沙S6MF01002 201 1 2 2 1
上面到下面的样子
city style color size qty
长沙S6MF01002 152 46 1
长沙S6MF01002 152 48 2
长沙S6MF01002 152 50 2
长沙S6MF01002 152 52 1
长沙S6MF01002 201 46 1
长沙S6MF01002 201 48 2
长沙S6MF01002 201 50 2
长沙S6MF01002 201 52 1 Select City,Style,Color,[46] From Test Union all
Select City,Style,Color,[48] From Test Union all
Select City,Style,Color,[50] From Test Union all
Select City,Style,Color,[52] From Test 就可以了。