SQL - 难以查询 - 将多行SUM整合到列中

时间:2012-12-28 03:39:07

标签: sql sql-server-2008-r2

我正在尝试开发一个小问题。

以下是我的表格: -

帐户表

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

基本上,客户可以多次在Accounts表中,因为每个客户端可以有多个帐户。

帐户类型将始终以相同的字符开头,但是根据这些帐户中有多少个数字可以是真实的,后续帐户将始终是一个末日,然后是一个数字......例如。第一个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

* 有两个不同的WHERE条款的原因是因为我不能只使用SUP1%,因为像SUP12这样的帐户与SUP1不同。

此查询工作正常,但它只为SUP帐户类型的列表生成一个列表。 如何为每种帐户类型在多列中生成相同类型的输出?

我正在使用Microsoft SQL 2008 R2

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

我不确定其他帐户的确切逻辑是什么,所以我只看前三个字符。

答案 2 :(得分: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

现在,您必须为要创建的所有列重复此逻辑。