2012-12-28 53 views
4

我對我正在嘗試開發的查詢有一個小挑戰。SQL - 查詢困難 - 將多行整列成列

這裏是我的表是什麼樣子: -

賬表

ClientNo  AccountType   Balance 
    1234    SUP1    25 
    1234   SUP1.1    35 
    1234    RET1    20 
    1111    SUP1    50 
    1111    DIS4    60 

我試圖得到一個結果,看起來像以下內容: -

ClientNo TotSupBal TotSuppAccts TotRetBal TotRetAccts TotDisBal TotDisAccts 
1234   70    2   20   1   0    0 
1111   50    1   0   0   60   1 

本質上客戶端可以多次進入帳戶表,因爲每個客戶端可以有多個帳戶。

賬戶類型總是以相同的字符開始,但取決於這些賬戶中有多少賬戶可以是真正的任何賬戶,並且隨後的賬戶將永遠是一個騙子,然後是一個數字......例如,第一SUP帳戶簡直是SUP1,但是接下來的SUP的帳戶將被SUP1.1,然後SUP1.2等等

我寫了下面的查詢

SELECT ClientNo, SUM(Balance) AS TotSupBal, COUNT(AccountType) AS TotSuppAccts 
FROM Account 
WHERE (AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1') 
GROUP BY ClientNo 

* 的原因有2個不同的WHERE子句是因爲我不能只使用SUP1%,因爲有像SUP12這樣的賬戶與SUP1不同。

此查詢可以正常工作,但是它只會爲SU​​P的帳戶類型生成列表。 但是,如何爲每種帳戶類型生成相同類型的輸出,但跨越多列?

我正在使用Microsoft SQL 2008 R2

回答

0

讓我假設您知道帳戶類型是提前。在這種情況下,你只是想有條件聚集總和:

select clientNo, 
     sum(case when (AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1') 
       then Balance 
      end) as TotSupBal, 
     sum(case when (AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1') 
       then 1 
       else 0 
      end) as TotSupAccts, 
     sum(case when left(AccountType, 3) = 'RET' 
       then Balance 
      end) as TotRetBal, 
     sum(case when left(AccountType, 3) = 'RET' 
       then 1 
       else 0 
      end) as TotRetAccts, 
     . . . 
from account 
group by clientNo 

我不知道確切的邏輯是什麼其他帳戶,所以我只是在尋找前三個字符。

0
SELECT 
    ClientNo, 
    SUM(Balance) AS TotSupBal, 
    COUNT(AccountType) AS TotSuppAccts, 
    ret_bal AS TotRetBal, 
    total_ret AS TotRetAccts 
FROM 
    Account, 
    (
     SELECT 
      ClientNo c_num, 
      SUM(Balance) AS ret_bal, 
      COUNT(AccountType) total_ret 
     WHERE AccountType LIKE 'RET%' 
     GROUP BY ClientNo 
    ) Table1RET_type -- Your name for new table(You create new temporary table for you select) 
WHERE 
    ((AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1')) 
    AND Table1RET_type.c_num = ClientNo -- This is called join Table(google it for more info) 
GROUP BY ClientNo 

現在,您必須對您要創建的所有列重複此邏輯。

3

PIVOT是你需要什麼>>http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

這裏是一個完全可行的解決方案:

WITH Accounts (AccountCategory, ClientNo, Balance) as (
    select 
    case 
     when AccountType like 'SUP%' then 'sup' 
     when AccountType like 'RET%' then 'ret' 
     when AccountType like 'DIS%' then 'dis' 
    end as AccountCategory, 
    ClientNo, 
    Balance 
    from Account 
) 
select * from (
    select ClientNo, sup as TotSupBal, ret as TotRetBal, dis as TotDisBal from Accounts as SourceTable PIVOT (
    SUM(Balance) 
    FOR AccountCategory IN ([sup], [ret], [dis]) 
) as pt 
) as sums inner join (
    select ClientNo, sup as TotSupAccts, ret as TotRetAccts, dis as TotDisAccts from Accounts as SourceTable PIVOT (
    COUNT(Balance) 
    FOR AccountCategory IN ([sup], [ret], [dis]) 
) as pt 
) as counts on sums.ClientNo = counts.ClientNo 

嘗試在SqlFiddle:http://sqlfiddle.com/#!6/d5e91/26