2010-05-06 27 views
1

是的,這是另一個透視問題......我已經讀過幾乎所有以前的問題,我似乎無法破解我所需要的查詢。SQL條件透視

這裏是我的表如下所示:

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 

最後三位列(週轉,分期付款,&按揭)規定的列應如何捲成的類型。每個結果都需要基於類型和行數的三列。結果應該是多列的一行。下面是結果應該是什麼樣子:

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 

你怎麼支點,基於比特字段(週轉,分期付款,&按揭),並保持適當的數量,使得每一列得到計數#追加到它?

回答

3

這必須用動態SQL來完成。首先,您需要確定每種類型的最大數量(並且可能還會將3位列轉換爲單個LOAN_TYPE列,因爲這是您的分區),然後使用ROW_NUMBER()OVER(分區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來生成該列表,但它會使系統稍微不具有前瞻性。

這將產生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 
+0

我與第三方PDF工具,它允許你在表單字段的數據飼料工作。我很樂意在C#中完成這一切,但這需要做大量的工作來改變當前的實現。我目前使用來自SQL Server 2005數據庫的通用存儲過程來提供這些數據。 – 2010-05-06 04:10:25

+0

@Coov編輯我的答案,給出一個完全可操作的解決方案 - 不用動態生成SQL來獲得最終的PIVOT列表。 – 2010-05-06 15:22:05

+0

我想要動態數據透視表,但由於pdf文檔有一組字段,我認爲你的解決方案會做到這一點。關於未來的證明,我認爲任何更改都需要新的文檔類型,因此需要新的查詢,所以我認爲沒關係。感謝您的幫助! – 2010-05-06 15:27:42