我有以下表结构,我试图获取总计和小计并显示值的汇总。
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 |
答案 0 :(得分: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
答案 1 :(得分: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
我将此question用于层次结构示例。
<强>输出:强>
| 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 |
答案 2 :(得分: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
答案 3 :(得分: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小提琴here
结果:
| 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 |