gpt4 book ai didi

sql-server - 基于 SQL Server 中的一列透视多列

转载 作者:行者123 更新时间:2023-12-02 07:05:32 25 4
gpt4 key购买 nike

我在 SQL Server 2008R2 中有以下源表和目标表。如何在 TSQL 中进行数据透视将 SourceTbl 转换为 DestTbl?希望 empIndex 能以某种方式帮助枢轴。

来源表

empId    empIndex    empState    empStDate    empEndDate
========================================================
10 1 AL 1/1/2012 12/1/2012
10 2 FL 2/1/2012 2/1/2013
15 1 FL 3/20/2012 1/1/2099

目标表

empId    empState1  empState1StDate    empState1EndDt    empState2  empState2StDate    empState2EndDt
=========================================================================================================
10 AL 1/1/2012 12/1/2012 FL 2/1/2012 2/1/2013
15 FL 3/20/2012 1/1/2099 NULL NULL NULL

最佳答案

由于您使用的是 SQL Server,因此有多种不同的方法可以将行转换为列。您可以将聚合函数与 CASE 表达式一起使用:

select empid,
max(case when empindex = 1 then empstate end) empState1,
max(case when empindex = 1 then empStDate end) empStDate1,
max(case when empindex = 1 then empEndDate end) empEndDate1,
max(case when empindex = 2 then empstate end) empState2,
max(case when empindex = 2 then empStDate end) empStDate2,
max(case when empindex = 2 then empEndDate end) empEndDate2
from sourcetbl
group by empid;

参见SQL Fiddle with Demo .

如果您想使用 PIVOT 函数来获取结果,那么我建议首先取消透视列 empStateempStDateempEndDate所以你首先会有多行。您可以使用 UNPIVOT 函数或 CROSS APPLY 来转换代码将是的数据:

select empid, col+cast(empindex as varchar(10)) col,  value
from sourcetbl
cross apply
(
select 'empstate', empstate union all
select 'empstdate', convert(varchar(10), empstdate, 120) union all
select 'empenddate', convert(varchar(10), empenddate, 120)
) c (col, value);

参见Demo 。一旦数据被取消透视,您就可以应用 PIVOT 函数,因此最终代码将是:

select empid,
empState1, empStDate1, empEndDate1,
empState2, empStDate2, empEndDate2
from
(
select empid, col+cast(empindex as varchar(10)) col, value
from sourcetbl
cross apply
(
select 'empstate', empstate union all
select 'empstdate', convert(varchar(10), empstdate, 120) union all
select 'empenddate', convert(varchar(10), empenddate, 120)
) c (col, value)
) d
pivot
(
max(value)
for col in (empState1, empStDate1, empEndDate1,
empState2, empStDate2, empEndDate2)
) piv;

参见SQL Fiddle with Demo .

如果您的 empindex 数量有限,那么上述版本将非常有效,但如果没有,那么您可以使用动态 SQL:

DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(empindex as varchar(10)))
from SourceTbl
cross apply
(
select 'empstate', 1 union all
select 'empstdate', 2 union all
select 'empenddate', 3
) c (col, so)
group by col, so, empindex
order by empindex, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')

set @query = 'SELECT empid,' + @cols + '
from
(
select empid, col+cast(empindex as varchar(10)) col, value
from sourcetbl
cross apply
(
select ''empstate'', empstate union all
select ''empstdate'', convert(varchar(10), empstdate, 120) union all
select ''empenddate'', convert(varchar(10), empenddate, 120)
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '

execute sp_executesql @query;

请参阅 SQL Fiddle with Demo

您可以使用这些查询 INSERT INTO 您的 DestTbl,或者您现在可以通过查询来获取所需的结果,而不是以此格式存储数据。

这些查询以以下格式放置数据:

| EMPID | EMPSTATE1 | EMPSTDATE1 | EMPENDDATE1 | EMPSTATE2 | EMPSTDATE2 | EMPENDDATE2 |
---------------------------------------------------------------------------------------
| 10 | AL | 2012-01-01 | 2012-12-01 | FL | 2012-02-01 | 2013-02-01 |
| 15 | FL | 2012-03-20 | 2099-01-01 | (null) | (null) | (null) |

关于sql-server - 基于 SQL Server 中的一列透视多列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18023479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com