Sql 将堆叠数据转换为水平数据
此查询:Sql 将堆叠数据转换为水平数据,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,此查询: ; with numbered as ( select *, -- Assign number to each record -- Numbering is separate for each pair of MLISNPI and CLIENT_ID1 -- Highest [Sum of desc] will get number 1 and so forth Rank() over (partition by [MLISN
; with numbered as
(
select *,
-- Assign number to each record
-- Numbering is separate for each pair of MLISNPI and CLIENT_ID1
-- Highest [Sum of desc] will get number 1 and so forth
Rank() over (partition by [MLISNPI]
order by [Sum of count] desc) rn
from [TargettingReport]
),
ctemain as (
select [MLISNPI],
[CLIENT_ID1],
[Sum of count]
from numbered
)
select * from ctemain
正在返回此示例数据:
+----------+------------+--------------+
| MLISNPI | CLIENT_ID1 | Sum of count |
+----------+------------+--------------+
| 03001363 | 101522 | 436 |
| 03001363 | 101596 | 0 |
| 03001363 | 101597 | 0 |
| 03002312 | 102165 | 66 |
| 03002742 | 100062 | 1 |
| 03002742 | 211074 | 1229 |
| 03006958 | 102235 | 21 |
| 03014986 | 213926 | 5 |
| 03016270 | 213143 | 3 |
| 03023284 | 212876 | 44 |
| 03023284 | 213801 | 55 |
| 03023821 | 100218 | 0 |
| 03028812 | 211144 | 133 |
| 03041666 | 100236 | 346 |
| 03041666 | 103164 | 65 |
| 03051731 | 213402 | 157 |
| 03058777 | 100572 | 28 |
| 03065509 | 101632 | 29 |
| 03071952 | 213632 | 6 |
| 03072059 | 101506 | 4 |
| 03081449 | 100087 | 398 |
| 03083205 | 214311 | 7 |
| 03117698 | 210178 | 203 |
| 03121302 | 214008 | 9 |
| 03139502 | 102179 | 1635 |
| 03147455 | 216022 | 21 |
| 03149204 | 211425 | 1 |
| 03186883 | 215748 | 1 |
| 03186883 | 215749 | 10 |
| 03190331 | 212289 | 26 |
| 03800285 | 101108 | 8052 |
| 03800285 | 101596 | 0 |
| 03800285 | 101597 | 0 |
| 03800350 | 212419 | 9 |
| 03800616 | 110461 | 0 |
| 03800616 | 213456 | 3 |
| 03802018 | 103136 | 32 |
| 03803412 | 201257 | 3 |
+----------+------------+--------------+
但是我实际上需要像下面这样的数据,按照MLISNPI
:
+----------+-----------+-------------+------------+-------------+-------------+----------+
| MLISNPI | clientid1 | sumofcount1 | clientid 2 | sumofcount2 | client id 3 | sum of 3 |
+----------+-----------+-------------+------------+-------------+-------------+----------+
| 03001363 | 101522 | 436 | 101596 | 0 | 101597 | 0 |
| 03002312 | 102165 | 66 | | | | |
| 03002742 | 100062 | 1 | 211074 | 1229 | | |
| 03006958 | 102235 | 21 | | | | |
| 03014986 | 213926 | 5 | | | | |
| 03016270 | 213143 | 3 | | | | |
| 03023284 | 212876 | 44 | 213801 | 55 | | |
+----------+-----------+-------------+------------+-------------+-------------+----------+
我如何获得这种格式的数据
以下是创建表:
CREATE TABLE [dbo].[TargettingReport](
[MLISNPI] [varchar](50) NULL,
[IMS_PRESCRIBER_ID] [varchar](50) NULL,
[CLIENT_ID1] [varchar](50) NULL,
[Sum of count] [int] NULL
) ON [PRIMARY]
请,您学习“Pivot”,您可以这样做: 声明@cols为NVARCHAR(最大值), @查询为NVARCHAR(最大值)
请,您学习“Pivot”,您可以这样做: 声明@cols为NVARCHAR(最大值), @查询为NVARCHAR(最大值)
您需要使用
枢轴执行此操作。如果您知道将拥有的列数,则可以使用静态版本
这将执行UNPIVOT
和PIVOT
操作,将行编号()分配给每列,然后进行转换:
select *
from
(
select MLISNPI,
cast(value as int) value,
case col
when 'client_id1' then 'clientid_' + cast(rn as varchar(10))
when 'SumofCount' then 'SumofCount_' + cast(rn as varchar(10))
end col
from
(
select MLISNPI, Client_id1, cast(SumOfCount as varchar(50)) SumofCount,
row_number() over(partition by MLISNPI order by Client_id1) rn
from TargettingReport
) x
unpivot
(
value
for col in (client_id1, sumofcount)
) u
) x1
pivot
(
sum(value)
for col in ([clientid_1], [SumofCount_1],
[clientid_2], [SumofCount_2],
[clientid_3], [SumofCount_3])
) p
看见
如果将有未知数量的row\u number()
s应用于列,则可以使用动态sql:
DECLARE @colsPivot AS NVARCHAR(MAX),
@colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SET @colsUnPivot
= stuff((select ','
+quotename(C.name )
from sys.columns as C
where C.object_id = object_id('TargettingReport') and
C.name IN ('CLIENT_ID1', 'SumOfCount')
for xml path('')), 1, 1, '')
SET @colsPivot
= stuff((select ','+quotename(case when C.name = 'client_id1' then 'clientid' else c.name end + '_' + cast(rn as varchar(10)))
from sys.columns as C
cross apply
(
select row_number() over(partition by MLISNPI order by Client_id1) rn
from TargettingReport
) x
where C.object_id = object_id('TargettingReport') and
C.name IN ('CLIENT_ID1', 'SumOfCount')
group by name, rn
order by rn
for xml path('')), 1, 1, '')
set @query
= '
select *
from
(
select MLISNPI,
cast(value as int) value,
case col
when ''client_id1'' then ''clientid_'' + cast(rn as varchar(10))
when ''SumofCount'' then ''SumofCount_'' + cast(rn as varchar(10))
end col
from
(
select MLISNPI, Client_id1, cast(SumOfCount as varchar(50)) SumofCount,
row_number() over(partition by MLISNPI order by Client_id1) rn
from TargettingReport
) x1
unpivot
(
value
for col in (' + @colsUnPivot + ')
) unpvt
) x2
pivot
(
sum(value)
for col in(' + @colsPivot +')
)p'
exec(@query)
请参见您需要使用枢轴执行此操作。如果您知道将拥有的列数,则可以使用静态版本
这将执行UNPIVOT
和PIVOT
操作,将行编号()分配给每列,然后进行转换:
select *
from
(
select MLISNPI,
cast(value as int) value,
case col
when 'client_id1' then 'clientid_' + cast(rn as varchar(10))
when 'SumofCount' then 'SumofCount_' + cast(rn as varchar(10))
end col
from
(
select MLISNPI, Client_id1, cast(SumOfCount as varchar(50)) SumofCount,
row_number() over(partition by MLISNPI order by Client_id1) rn
from TargettingReport
) x
unpivot
(
value
for col in (client_id1, sumofcount)
) u
) x1
pivot
(
sum(value)
for col in ([clientid_1], [SumofCount_1],
[clientid_2], [SumofCount_2],
[clientid_3], [SumofCount_3])
) p
看见
如果将有未知数量的row\u number()
s应用于列,则可以使用动态sql:
DECLARE @colsPivot AS NVARCHAR(MAX),
@colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SET @colsUnPivot
= stuff((select ','
+quotename(C.name )
from sys.columns as C
where C.object_id = object_id('TargettingReport') and
C.name IN ('CLIENT_ID1', 'SumOfCount')
for xml path('')), 1, 1, '')
SET @colsPivot
= stuff((select ','+quotename(case when C.name = 'client_id1' then 'clientid' else c.name end + '_' + cast(rn as varchar(10)))
from sys.columns as C
cross apply
(
select row_number() over(partition by MLISNPI order by Client_id1) rn
from TargettingReport
) x
where C.object_id = object_id('TargettingReport') and
C.name IN ('CLIENT_ID1', 'SumOfCount')
group by name, rn
order by rn
for xml path('')), 1, 1, '')
set @query
= '
select *
from
(
select MLISNPI,
cast(value as int) value,
case col
when ''client_id1'' then ''clientid_'' + cast(rn as varchar(10))
when ''SumofCount'' then ''SumofCount_'' + cast(rn as varchar(10))
end col
from
(
select MLISNPI, Client_id1, cast(SumOfCount as varchar(50)) SumofCount,
row_number() over(partition by MLISNPI order by Client_id1) rn
from TargettingReport
) x1
unpivot
(
value
for col in (' + @colsUnPivot + ')
) unpvt
) x2
pivot
(
sum(value)
for col in(' + @colsPivot +')
)p'
exec(@query)
请看,根据您给我们的信息,clientid
如何在client1
、clientid 2
或clientid 3
中结束尚不清楚。你能描述一下这些列应该如何生成,就好像你是手动生成的一样吗?@NathanielFord,谢谢。client2将是同一个MLISNPI,但它的(sumofcount)将是该特定MLISNPI的第二大,而client3它的sumofcount将是该特定MLISNPI的第三大。使用示例插入为TargettingReport创建一个可行的表定义会有所帮助。你可以把它放在上面。@RossPresser我已经添加了一个创建表,非常感谢rfo ryour的帮助!根据您给我们的信息,clientid
如何在client1
、clientid 2
或clientid 3
中结束尚不清楚。你能描述一下这些列应该如何生成,就好像你是手动生成的一样吗?@NathanielFord,谢谢。client2将是同一个MLISNPI,但它的(sumofcount)将是该特定MLISNPI的第二大,而client3它的sumofcount将是该特定MLISNPI的第三大。使用示例插入为TargettingReport创建一个可行的表定义会有所帮助。你可以把它放在上面。@RossPresser我已经添加了一个创建表,非常感谢rfo ryour的帮助!