【问题标题】:SQL - Difficult query - SUM multiple rows into columnsSQL - 困难查询 - 将多行汇总到列中
【发布时间】:2012-12-28 03:39:06
【问题描述】:

我正在尝试开发的查询遇到一个小挑战。

这是我的桌子的样子:-

帐户表

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

*之所以有 2 个不同的 WHERE 子句,是因为我不能只使用 SUP1%,因为有像 SUP12 这样的帐户与 SUP1 不同。

此查询工作正常,但它只为 SUP 帐户类型的那些生成列表。 我怎样才能产生相同类型的输出,但在每个帐户类型的多个列中?

我正在使用 Microsoft SQL 2008 R2

【问题讨论】:

    标签: sql sql-server-2008-r2


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

      假设您事先知道帐户类型是什么。在这种情况下,您只需要一个条件聚合总和:

      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
      

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

      【讨论】:

        【解决方案3】:
        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
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-26
          • 2010-12-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多