Pivot conditionnel SQL

Oui, c'est une autre question Pivot … J'ai lu presque toutes les questions précédentes et je ne peux pas sembler bidouiller une requête qui fait ce dont j'ai besoin.

Voici à quoi ressemble ma table:

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 

Les trois dernières colonnes (Revolving, Installment, & Mortgage) dictent la manière dont les colonnes doivent être regroupées dans un type. Chaque résultat nécessite trois colonnes en fonction du type et de son nombre de lignes. Le résultat devrait être une ligne avec plusieurs colonnes. Voici à quoi devrait ressembler le résultat:

 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 

Comment pivotez-vous en fonction des champs de bits (Revolving, Acount et Hypothèque) et conservez le nombre approprié de façon à ce que chaque colonne count # ajoutée?

Cela devrait être fait avec SQL dynamic. Vous devez d'abord déterminer le nombre maximum de chaque type (et probablement convertir les colonnes de 3 bits en une seule colonne LOAN_TYPE puisque c'est votre partition) sur l'set de votre population, puis utiliser un ROW_NUMBER () OVER (PARTITION PAR LOAN_TYPE ORDER BY FirmName ) sur datatables normalisées corrélées avec cela afin de mettre les choses dans leur colonne de droite.

Je dois requestr à quel point il est important de le faire dans la database – parce que le schéma n'est pas corrigé, il est assez difficile de voir l'utilité de le faire de cette façon.

Pourtant, seulement un peu plus complexe que la plupart des pivots dynamics, donc si les indices ci-dessus ne vous y mènent pas, et que vous voulez quand même que je prenne un coup, je vais essayer de postr un vrai code de travail plus tard.

 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 

Votre principal problème restant est la list finale de PIVOT (vous pouvez générer dynamicment comme je l'ai mentionné) et la security de type car tout est conforme à varchar (50) dans l'étape de valeur d'entité avant le PIVOT final.

De plus, si les drapeaux ne sont pas mutuellement exclusifs, vous aurez des duplicates …

Je pense que si vous utilisez un système de génération de formulaire que la list PIVOT finale est relativement fixe, vous pouvez laisser le SQL dynamic pour générer cette list, mais cela rendrait le système légèrement non-futur-preuve.

Cela générera la list des pivots (pourrait être simplifiée):

 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