这必须用动态sql来完成。首先,您需要确定整个填充中每种类型的最大数量(可能还需要将3位列转换为单个loan_type列,因为这是您的分区),然后在规范化数据上(按firmname的loan_type order进行分区)使用row_number()与之相关,以便将事情放在其右栏中。
我不得不问在数据库中这样做有多重要——因为模式没有被修复,所以很难看到这样做的实用性。
不过,只比大多数动态轴心稍微复杂一点,所以如果上面的提示不能让您理解,而且您仍然希望我尝试一下,我稍后将尝试发布一些实际的工作代码。
SET NOCOUNT ON
DECLARE @t AS TABLE
(
FirmName varchar(50) NOT NULL
,Account varchar(50) NOT NULL
,Balance money NOT NULL
,Pmt money NOT NULL
,Revolving bit NOT NULL
,Installment bit NOT NULL
,Mortgage bit NOT NULL
) ;
INSERT INTO @t
VALUES ('Amex', '12345', 10000, 2000, 1, 0, 0) ;
INSERT INTO @t
VALUES ('Discover', '54321', 20000, 4000, 1, 0, 0) ;
INSERT INTO @t
VALUES ('Chase', '13579', 100000, 1500, 0, 0, 1) ;
INSERT INTO @t
VALUES ('Wells Fargo', '2468', 40000, 900, 0, 1, 0) ;
WITH n1
AS (
SELECT FirmName
,Account
,Balance
,Pmt
,LoanType
,LoanTypeFlag
FROM @t UNPIVOT ( LoanTypeFlag FOR LoanType IN ([Revolving], [Installment], [Mortgage]) ) AS unpvt
),
n2
AS (
SELECT FirmName
,Balance
,Pmt
,LoanType
FROM n1
WHERE LoanTypeFlag = 1
),
n3
AS (
SELECT FirmName
,Balance
,Pmt
,LoanType
,ROW_NUMBER() OVER (PARTITION BY LoanType ORDER BY FirmName) AS SequenceNumber
FROM n2
),
n4
AS (
SELECT LoanType + CONVERT(varchar, SequenceNumber) AS Column_Prefix
,FirmName AS Firm
,CONVERT(varchar(50), Balance) AS Balance
,CONVERT(varchar(50), Pmt) AS Pmt
FROM n3
),
n5
AS (
SELECT Column_Prefix + '_' + Col AS Col_Nm
,Val
FROM n4 UNPIVOT ( Val FOR Col IN ([Firm], [Balance], [Pmt]) ) AS unpvt
)
SELECT *
FROM n5 PIVOT ( MAX(Val) FOR Col_Nm IN ([Installment1_Firm], [Installment1_Balance], [Installment1_Pmt],
[Mortgage1_Firm], [Mortgage1_Balance], [Mortgage1_Pmt], [Revolving1_Firm],
[Revolving1_Balance], [Revolving1_Pmt], [Revolving2_Firm],
[Revolving2_Balance], [Revolving2_Pmt]) ) AS pvt
剩下的主要问题是最后一个pivot列表(可以像我提到的那样动态地生成这个列表)和类型安全性,因为在最后一个pivot之前的entity-value阶段,所有内容都符合varchar(50)。
另外,如果位标志不是互斥的,则会有一些重复项…
我认为,如果您使用的表单生成系统的最终透视表列表相对固定,因此您可以不使用动态sql来生成该列表,但这会使系统稍微不适合将来使用。
这将生成pivot_列表(可以简化):
WITH n1
AS (
SELECT FirmName
,Account
,Balance
,Pmt
,LoanType
,LoanTypeFlag
FROM @t UNPIVOT ( LoanTypeFlag FOR LoanType IN ([Revolving], [Installment], [Mortgage]) ) AS unpvt
),
n2
AS (
SELECT FirmName
,Balance
,Pmt
,LoanType
FROM n1
WHERE LoanTypeFlag = 1
),
n3
AS (
SELECT FirmName
,Balance
,Pmt
,LoanType
,ROW_NUMBER() OVER (PARTITION BY LoanType ORDER BY FirmName) AS SequenceNumber
FROM n2
),
n4
AS (
SELECT LoanType + CONVERT(varchar, SequenceNumber) AS Column_Prefix
,FirmName AS Firm
,CONVERT(varchar(50), Balance) AS Balance
,CONVERT(varchar(50), Pmt) AS Pmt
FROM n3
),
n5
AS (
SELECT Column_Prefix + '_' + Col AS Col_Nm
,Val
FROM n4 UNPIVOT ( Val FOR Col IN ([Firm], [Balance], [Pmt]) ) AS unpvt
),
pivot_list(pivot_list)
AS (
SELECT ',' + QUOTENAME(Col_Nm)
FROM n5
FOR XML PATH('')
)
SELECT STUFF(pivot_list, 1, 1, '') AS pivot_list
FROM pivot_list