是的,这是另一个Pivot问题......我已经阅读了几乎所有以前的问题,我似乎无法将我所需要的查询整合在一起。
以下是我的表格:
FirmName Account Balance Pmt Revolving Installment Mortgage
Amex 12345 10000 2000 1 0 0
Discover 54321 20000 4000 1 0 0
Chase 13579 100000 1500 0 0 1
Wells Fargo 2468 40000 900 0 1 0
最后三位列(Revolving,Installment和& Mortgage)规定了如何将列卷入一个类型。每个结果都需要三列,具体取决于类型及其行数。结果应该是一行有很多列。结果如下:
Revolving1_Firm Revolving1_Balance Revolving1_Pmt Revolving2_Firm Revolving2_Balance Revolving2_Pmt Realestate1_Firm Realestate1_Balance Realestate1_Pmt Vehicle1_Firm Vehicle1_Balance Vehicle1_Pmt
Amex 10000 2000 Discover 20000 4000 Chase 100000 1500 Wells Fargo 40000 900
如何根据位字段(旋转,分期付款和抵押贷款)进行调整并保留正确的计数,以便每列都附加计数#?
答案 0 :(得分:3)
这必须使用动态SQL来完成。首先,您需要确定每个类型的最大数量(并且可能还将3位列转换为单个LOAN_TYPE列,因为这是您的分区),然后使用ROW_NUMBER()OVER(PARTITION BY LOAN_TYPE ORDER BY FirmName) )超过与之相关的标准化数据,以便将事物放在右栏中。
我不得不问在数据库中执行此操作有多重要 - 因为架构不是固定的,所以很难看到这样做的实用程序。
尽管如此,只有比大多数动态枢轴稍微复杂一点,所以如果上面的提示没有让你到达那里,而你仍然希望我对它进行刺激,我会尝试稍后发布一些实际的工作代码
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之前的实体值阶段,一切都符合varchar(50)。
此外,如果位标志不是互斥的,那么您将有一些重复...
我认为如果您使用的是表单生成系统,最终的PIVOT列表是相对固定的,那么您可以不使用动态SQL来生成该列表,但这会使系统略微不具备面向未来的能力。 / p>
这将生成pivot_list(可以简化):
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