4

我有以下表结构,我试图为其获取总计和小计并显示值的汇总。

ChartOfAccounts(AccountNumber, AccountDescription, ParentAccountNumber, IsControlAccount)
Ledger(LedgerId, JournalId, AccountNumber, IsDebit, Amount)

我已经设法使用 CTE 来获得所需的父子关系,但我不确定如何使用它来获取汇总到父账户中的控制账户余额。

到目前为止,我已经设法将以下查询放在一起,这并不完全是我想要的 --> SQL Fiddle。当前查询似乎没有正确汇总和分组父子总数。(我已经从小提琴中排除了年、月列)

描述问题的另一种方式是,所有控制帐户都应具有其子帐户的总数。

我需要的输出如下(年、月、AccountNumber、AccountDescription、DebitBalance、CreditBalance、Balance)

|Account#|Acc Desc                                 | DR     | CR     | BAL    |
|1000    |Accounts Receivable                      |10000   |5000    |5000    |
|1200    |Buyer  Receivables                       |5000    |0       |5000    |
|12001   |Buyer  Receivables - Best Buy            |5000    |0       |5000    |
|1500    |Offers                                   |5000    |5000    |0       |
|4000    |Accounts Payable                         |        |4475.06 |4475.06 |  
|4100    |Supplier Invoice Payables                |        |4475.06 |4475.06 |  
|41002   |Supplier Invoice Payables - Knechtel     |        |4475.06 |4475.06 |  
|6000    |Revenue                                  |        |524.93  |524.93  |  
|6100    |Membership Fees Revenue                  |        |        |0       |  
|6200    |Processing Fees Revenue                  |        |100     |100     |  
|62002   |Processing Fees Revenue - Knechtel       |        |100     |100     |  
|6300    |Fees Revenue                             |        |424.93  |424.93  |  
|63002   |Fees Revenue  - Knechtel                 |        |424.93  |424.93  |  
4

4 回答 4

2

这是我想出的,并且能够非常接近匹配您想要的输出

WITH CTEAcc 
AS
(
    SELECT
        coa.accountDescription,coa.accountnumber,coa.accountnumber as parentaccount
        FROM ChartOfAccounts coa
  where iscontrolaccount=1
  union all select c.accountdescription, coa.accountnumber, c.ParentAccount 
    from chartofaccounts coa
    inner join cteacc c on coa.ParentAccountNumber=c.accountnumber

)

select parentaccount as [Account#], accountdescription as [Acc Desc], 
sum(case when isdebit=1 then amount else 0 end) as DR,
sum(case when isdebit=0 then amount else 0 end) as CR,
sum(case when isdebit=1 then amount else 0 end)-sum(case when isdebit=0 then amount else 0 end) as BAL
from (select c.accountdescription, c.accountnumber, 
      c.parentaccount, l.isdebit, l.amount 
      from cteacc c
left join ledger l
  on c.accountnumber=l.accountnumber
union all select c.accountdescription, 
      c.accountnumber, c.accountnumber as parentaccount, 
      l.isdebit, l.amount 
      from ChartOfAccounts c
      inner join ledger l
  on c.accountnumber=l.accountnumber where amount<>0) f
group by parentaccount, accountdescription
order by parentaccount

这是 sql 小提琴:http ://www.sqlfiddle.com/#!3/d94bc/106

于 2014-03-18T23:07:38.447 回答
1

又一个变种。保留层次结构和 iscontrol 字段仅供参考。首先,它将帐户层次结构与每个帐户相关联(递归 cte)。然后,对于每个帐户,根据层次结构位置(以及它是否是控制帐户)计算该帐户的分类帐项目总和。最后,包装在另一个查询中以计算余额并从输出中去除未使用的帐户。

WITH AccountHierarchy AS (

    SELECT AccountNumber
          ,AccountDescription
          ,CAST(AccountNumber AS VARCHAR(MAX))
             + '/' AS AccountHierarchy
          ,IsControlAccount
      FROM ChartOfAccounts
      WHERE ParentAccountNumber IS NULL

    UNION ALL

    SELECT c.AccountNumber
          ,c.AccountDescription
          ,CAST(h.AccountHierarchy  AS VARCHAR(MAX))
             + CAST(c.AccountNumber AS VARCHAR(MAX))
             + '/' AS AccountHierarchy
          ,c.IsControlAccount
      FROM ChartOfAccounts c
      INNER JOIN AccountHierarchy h ON (c.ParentAccountNumber = h.AccountNumber)
      WHERE ParentAccountNumber IS NOT NULL
)

SELECT AccountNumber
      ,AccountDescription
      ,AccountHierarchy
      ,IsControlAccount
      ,DR
      ,CR
      ,CASE WHEN (DR IS NULL AND CR IS NULL) THEN NULL
            ELSE COALESCE(DR, 0) - COALESCE(CR, 0)
            END AS BAL

  FROM (SELECT h.AccountNumber
              ,h.AccountDescription
              ,h.AccountHierarchy
              ,h.IsControlAccount

              ,(SELECT SUM(l.Amount)
                  FROM Ledger l
                  INNER JOIN AccountHierarchy hd ON (l.AccountNumber = hd.AccountNumber)
                  WHERE l.IsDebit = 1
                    AND (    (h.IsControlAccount = 1 AND hd.AccountHierarchy LIKE h.AccountHierarchy + '%')
                          OR hd.AccountHierarchy = h.AccountHierarchy)
               ) AS DR

              ,(SELECT SUM(l.Amount)
                  FROM Ledger l
                  INNER JOIN AccountHierarchy hd ON (l.AccountNumber = hd.AccountNumber)
                  WHERE l.IsDebit = 0
                    AND (    (h.IsControlAccount = 1 AND hd.AccountHierarchy LIKE h.AccountHierarchy + '%')
                          OR hd.AccountHierarchy = h.AccountHierarchy)
               ) AS CR

          FROM AccountHierarchy h
        ) x

  WHERE NOT(CR IS NULL AND DR IS NULL)
  ORDER BY AccountHierarchy

我将此问题用于层次结构示例。

输出:

|        ACCOUNTNUMBER |                 ACCOUNTDESCRIPTION |                                                ACCOUNTHIERARCHY | ISCONTROLACCOUNT |     DR |        CR |        BAL |
|----------------------|------------------------------------|-----------------------------------------------------------------|------------------|--------|-----------|------------|
| 1000                 |                Accounts Receivable |                                           1000                / |                1 |  10000 |      5000 |       5000 |
| 1200                 |                 Buyer  Receivables |                      1000                /1200                / |                1 |   5000 |    (null) |       5000 |
| 12001                |      Buyer  Receivables - Best Buy | 1000                /1200                /12001               / |                0 |   5000 |    (null) |       5000 |
| 1500                 |                             Offers |                      1000                /1500                / |                0 |   5000 |      5000 |          0 |
| 4000                 |                   Accounts Payable |                                           4000                / |                1 | (null) | 4475.0685 | -4475.0685 |
| 4100                 |                 Supplier  Payables |                      4000                /4100                / |                1 | (null) | 4475.0685 | -4475.0685 |
| 41002                |      Supplier  Payables - Knechtel | 4000                /4100                /41002               / |                0 | (null) | 4475.0685 | -4475.0685 |
| 6000                 |                            Revenue |                                           6000                / |                1 | (null) |  524.9315 |  -524.9315 |
| 6200                 |            Processing Fees Revenue |                      6000                /6200                / |                1 | (null) |       100 |       -100 |
| 62002                | Processing Fees Revenue - Knechtel | 6000                /6200                /62002               / |                0 | (null) |       100 |       -100 |
| 6300                 |                       Fees Revenue |                      6000                /6300                / |                1 | (null) |  424.9315 |  -424.9315 |
| 63002                |            Fees Revenue - Knechtel | 6000                /6300                /63002               / |                0 | (null) |  424.9315 |  -424.9315 |
于 2014-03-20T00:32:01.643 回答
0

从您想要的输出开始,我提出了以下查询,该查询基于ParentAccountNumber. 仅需要子查询,因为我假设您想NULL在求和之前将任何值转换为 0(在 SQL 中,NULL+ 42 = NULL)。

with preresult as
(
    select acc.ParentAccountNumber as AccountNumber,
          acc.AccountDescription as "Acc Desc",
          ISNULL(ld.Amount, 0) as DR,
          ISNULL(lc.Amount, 0) as CR

    from ChartOfAccounts acc

    left outer join Ledger ld
    on (ld.AccountNumber = acc.AccountNumber AND ld.IsDebit = 1)

    left outer join Ledger lc
    on (lc.AccountNumber = acc.AccountNumber AND lc.IsDebit = 0)

    where acc.ParentAccountNumber is not null
)

select c.AccountNumber as "ACC",
      c.AccountDescription as "ACC DESC",
      sum(DR) as DR,
      sum(CR) as CR,
      sum(DR) - sum(CR) AS BL

from preresult p
join ChartOfAccounts c on (c.AccountNumber = p.AccountNumber)

group by c.AccountNumber, c.AccountDescription;

可以在这里找到 sqlfiddle:http ://www.sqlfiddle.com/#!3/d94bc/81/0

于 2014-03-18T22:02:14.757 回答
0

这似乎给了你你想要的东西:

;WITH recurs
AS
(
    SELECT C.AccountNumber, C.IsControlAccount, C.ParentAccountNumber, C.AccountDescription, 
            COALESCE((SELECT SUM(Amount) FROM Ledger WHERE AccountNumber = C.AccountNumber and IsDebit = 1), 0) AS DR,
            COALESCE((SELECT SUM(Amount) FROM Ledger WHERE AccountNumber = C.AccountNumber and IsDebit = 0), 0) AS CR,
            COALESCE((SELECT SUM(CASE WHEN IsDebit = 0 THEN Amount * -1 ELSE Amount END) FROM Ledger WHERE AccountNumber = C.AccountNumber), 0) AS BAL
    FROM ChartOfAccounts C
    WHERE IsControlAccount = 0
    UNION ALL
    SELECT C.AccountNumber, C.IsControlAccount, C.ParentAccountNumber, C.AccountDescription,
            r.DR, r.CR, R.BAL
    FROM ChartOfAccounts C
    INNER JOIN recurs r
        ON r.ParentAccountNumber = c.AccountNumber
)
SELECT R.AccountNumber, R.AccountDescription, SUM(R.DR) AS DR, SUM(R.CR) AS CR, SUM(R.BAL) AS BAL
FROM recurs R
WHERE NOT (R.DR = 0 AND R.CR = 0 AND R.BAL = 0)
GROUP BY R.AccountNumber, R.AccountDescription
ORDER BY AccountNumber

SQL小提琴在这里

结果:

|        ACCOUNTNUMBER |                 ACCOUNTDESCRIPTION |    DR |        CR |        BAL |
|----------------------|------------------------------------|-------|-----------|------------|
| 1000                 |                Accounts Receivable | 10000 |      5000 |       5000 |
| 1200                 |                 Buyer  Receivables |  5000 |         0 |       5000 |
| 12001                |      Buyer  Receivables - Best Buy |  5000 |         0 |       5000 |
| 1500                 |                             Offers |  5000 |      5000 |          0 |
| 4000                 |                   Accounts Payable |     0 | 4475.0685 | -4475.0685 |
| 4100                 |                 Supplier  Payables |     0 | 4475.0685 | -4475.0685 |
| 41002                |      Supplier  Payables - Knechtel |     0 | 4475.0685 | -4475.0685 |
| 6000                 |                            Revenue |     0 |  524.9315 |  -524.9315 |
| 6200                 |            Processing Fees Revenue |     0 |       100 |       -100 |
| 62002                | Processing Fees Revenue - Knechtel |     0 |       100 |       -100 |
| 6300                 |                       Fees Revenue |     0 |  424.9315 |  -424.9315 |
| 63002                |            Fees Revenue - Knechtel |     0 |  424.9315 |  -424.9315 |
于 2014-03-19T17:14:16.390 回答