2012-12-28 15 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