有条件总结-将两个查询合并为一个

时间:2019-08-04 03:12:31

标签: sql sql-server

我正在尝试计算我所有帐户的余额。一个帐户可以与许多交易相关。交易关联到两个帐户。一个帐户是将在transaction.debitaccountid中记入借方的帐户。另一个帐户将记入transaction.creditaccountid

一个事务可以由1:许多TransactionLines组成。这样一来,就可以在不同的类别或预算之间划分交易。

所以我的结构:

enter image description here

(我完全控制了结构,因此可以更改)

我正在尝试获取所有帐户及其余额的列表。稍后我将在linq(ef内核)中进行此操作。但是就目前而言,只是试图找到最有效的方法。

我陷入了两个查询的联合,我认为这不好。

;WITH cte AS (
Select a.ExternalId AS ExternalId, a.Name, SUM(tl.Amount) AS Amount, 1 AS Credit
FROM Account a
INNER JOIN [Transaction] t
ON t.CreditAccountId = a.Id 
INNER JOIN TransactionLine tl
ON tl.TransactionId = t.id
WHERE a.AccountTypeId = 1
GROUP BY a.Id, a.ExternalId, a.Name

UNION

Select a.ExternalId AS ExternalId, a.Name, SUM(tl.Amount) AS Amount, -1 AS Credit
FROM Account a
INNER JOIN [Transaction] t
ON t.DebitAccountId = a.Id 
INNER JOIN TransactionLine tl
ON tl.TransactionId = t.id
WHERE a.AccountTypeId = 1
GROUP BY a.Id, a.ExternalId, a.Name
)
SELECT ExternalId, Name, SUM(Amount * Credit) FROM cte
GROUP BY ExternalId, Name

我得到正确的答案,但这似乎效率不高。另外,我需要在链接中执行此操作,因此将是来自应用程序的两个查询,然后是在linq中处理的结果。

是否可以在单个SQL查询中执行此操作?也许用OR加入交易?但是然后,不确定是借项还是贷项价值。

也许我需要将金额存储在交易表中?但这可能会出错。可能会更容易并且可以变得安全吗?

编辑: 这几乎可行。但我不能正确分组:

Select a.ExternalId AS ExternalId, a.Name, 
SUM(tl.Amount) *  
case when t.CreditAccountId = a.Id then 1 
when t.DebitAccountId = a.Id then -1 end
as Amt 
FROM Account a
INNER JOIN [Transaction] t
ON (t.CreditAccountId = a.Id OR t.DebitAccountId = a.Id )
INNER JOIN TransactionLine tl
ON tl.TransactionId = t.id
WHERE a.AccountTypeId = 1
GROUP BY a.Id, a.ExternalId, a.Name, t.CreditAccountId, t.DebitAccountId

导致: enter image description here

需要将这些按“外部ID”和“名称”分组,并加上“金额”。

编辑2: 固定它。

Select a.ExternalId AS ExternalId, a.Name, 
SUM(tl.Amount *  
case when t.CreditAccountId = a.Id then 1 
when t.DebitAccountId = a.Id then -1 end)
as Amt 
FROM Account a
INNER JOIN [Transaction] t
ON (t.CreditAccountId = a.Id OR t.DebitAccountId = a.Id )
INNER JOIN TransactionLine tl
ON tl.TransactionId = t.id
WHERE a.AccountTypeId = 1
GROUP BY a.Id, a.ExternalId, a.Name--, t.CreditAccountId, t.DebitAccountId

结果:

enter image description here

1 个答案:

答案 0 :(得分:1)

希望我能正确理解您的问题。

我认为您可以使用ORCASE语句在同一查询中获得结果。请检查以下查询是否有帮助。

Select a.ExternalId AS ExternalId, a.Name, 
SUM(tl.Amount *  
case when t.CreditAccountId = a.Id then 1 
when t.DebitAccountId = a.Id then -1 end)
as Amt 
FROM Account a
INNER JOIN [Transaction] t
ON (t.CreditAccountId = a.Id OR t.DebitAccountId = a.Id )
INNER JOIN TransactionLine tl
ON tl.TransactionId = t.id
WHERE a.AccountTypeId = 1
GROUP BY a.Id, a.ExternalId, a.Name