SQL 查询 - 贷方、借方、余额
SQL query - credit , debit , balance
免责声明:我知道这个问题已经被问过很多次了,但我想要的只是一个替代方案。
table如下:
create table
Account
(Name varchar(20),
TType varchar(5),
Amount int);
insert into Account Values
('abc' ,'c', 500),
('abc', 'c', 700),
('abc', 'd', 100),
('abc', 'd', 200),
('ab' ,'c', 300),
('ab', 'c', 700),
('ab', 'd', 200),
('ab', 'd', 200);
预期结果很简单:
Name Balance
------ -----------
ab 600
abc 900
有效的查询是:
select Name, sum(case TType when 'c' then Amount
when 'd' then Amount * -1 end) as balance
from Account a1
group by Name.
我想要的是,是否有任何查询没有 'case' 语句(如子查询或自连接)以获得相同的结果?
当然可以。您可以使用带有 where
子句和 union all
:
的第二个查询
select name
, sum(Amount) balance
from Account a1
where TType when 'c'
group
by Name
union
all
select name
, sum(Amount * -1) balance
from Account a1
where TType when 'd'
group
by Name
或者这个,使用带有内联视图的 join
:
select name
, sum(Amount * o.mult) balance
from Account a1
join ( select 'c' cd
, 1 mult
from dual
union all
select 'd'
, -1
from dual
) o
on o.cd = a1.TType
group
by Name
老实说,我建议使用 case
...
使用字符的 ASCII 代码并尝试从那里开始。 'd' 为 100,'c' 为 99。未经测试的示例:
select Name, sum((ASCII(TType) - 100) * Amount * (-1)) + sum((ASCII(TType) - 99) * Amount * (-1)))) as balance from Account a1 group by Name.
我不推荐使用这种方法,但它是一种实现您想要的方法。
select t.Name, sum(t.cr) - sum(t.dr) as balance from (select Name, case TType when 'c' then sum(Amount) else 0 end as cr, case TType when 'd' then sum(Amount) else 0 end as dr from Account group by Name, TType) t group by t.Name;
这一定能帮到你!!
以下在 Microsoft SQL 服务器上为我工作。它也有 Brought Forward 余额
WITH tempDebitCredit AS (
Select 0 As Details_ID, null As Creation_Date, null As Reference_ID, 'Brought
Forward' As Transaction_Kind, null As Amount_Debit, null As Amount_Credit,
isNull(Sum(Amount_Debit - Amount_Credit), 0) 'diff'
From _YourTable_Name
where Account_ID = @Account_ID
And Creation_Date < @Query_Start_Date
Union All
SELECT a.Details_ID, a.Creation_Date, a.Reference_ID, a.Transaction_Kind,
a.Amount_Debit, a.Amount_Credit, a.Amount_Debit - a.Amount_Credit 'diff'
FROM _YourTable_Name a
where Account_ID = @Account_ID
And Creation_Date >= @Query_Start_Date And Creation_Date <= @Query_End_Date
)
SELECT a.Details_ID, a.Creation_Date, a.Reference_ID, a.Transaction_Kind,
a.Amount_Debit, a.Amount_Credit, SUM(b.diff) 'Balance'
FROM tempDebitCredit a, tempDebitCredit b
WHERE b.Details_ID <= a.Details_ID
GROUP BY a.Details_ID, a.Creation_Date, a.Reference_ID, a.Transaction_Kind,
a.Amount_Debit, a.Amount_Credit
Order By a.Details_ID Desc
免责声明:我知道这个问题已经被问过很多次了,但我想要的只是一个替代方案。
table如下:
create table
Account
(Name varchar(20),
TType varchar(5),
Amount int);
insert into Account Values
('abc' ,'c', 500),
('abc', 'c', 700),
('abc', 'd', 100),
('abc', 'd', 200),
('ab' ,'c', 300),
('ab', 'c', 700),
('ab', 'd', 200),
('ab', 'd', 200);
预期结果很简单:
Name Balance
------ -----------
ab 600
abc 900
有效的查询是:
select Name, sum(case TType when 'c' then Amount
when 'd' then Amount * -1 end) as balance
from Account a1
group by Name.
我想要的是,是否有任何查询没有 'case' 语句(如子查询或自连接)以获得相同的结果?
当然可以。您可以使用带有 where
子句和 union all
:
select name
, sum(Amount) balance
from Account a1
where TType when 'c'
group
by Name
union
all
select name
, sum(Amount * -1) balance
from Account a1
where TType when 'd'
group
by Name
或者这个,使用带有内联视图的 join
:
select name
, sum(Amount * o.mult) balance
from Account a1
join ( select 'c' cd
, 1 mult
from dual
union all
select 'd'
, -1
from dual
) o
on o.cd = a1.TType
group
by Name
老实说,我建议使用 case
...
使用字符的 ASCII 代码并尝试从那里开始。 'd' 为 100,'c' 为 99。未经测试的示例:
select Name, sum((ASCII(TType) - 100) * Amount * (-1)) + sum((ASCII(TType) - 99) * Amount * (-1)))) as balance from Account a1 group by Name.
我不推荐使用这种方法,但它是一种实现您想要的方法。
select t.Name, sum(t.cr) - sum(t.dr) as balance from (select Name, case TType when 'c' then sum(Amount) else 0 end as cr, case TType when 'd' then sum(Amount) else 0 end as dr from Account group by Name, TType) t group by t.Name;
这一定能帮到你!!
以下在 Microsoft SQL 服务器上为我工作。它也有 Brought Forward 余额
WITH tempDebitCredit AS (
Select 0 As Details_ID, null As Creation_Date, null As Reference_ID, 'Brought
Forward' As Transaction_Kind, null As Amount_Debit, null As Amount_Credit,
isNull(Sum(Amount_Debit - Amount_Credit), 0) 'diff'
From _YourTable_Name
where Account_ID = @Account_ID
And Creation_Date < @Query_Start_Date
Union All
SELECT a.Details_ID, a.Creation_Date, a.Reference_ID, a.Transaction_Kind,
a.Amount_Debit, a.Amount_Credit, a.Amount_Debit - a.Amount_Credit 'diff'
FROM _YourTable_Name a
where Account_ID = @Account_ID
And Creation_Date >= @Query_Start_Date And Creation_Date <= @Query_End_Date
)
SELECT a.Details_ID, a.Creation_Date, a.Reference_ID, a.Transaction_Kind,
a.Amount_Debit, a.Amount_Credit, SUM(b.diff) 'Balance'
FROM tempDebitCredit a, tempDebitCredit b
WHERE b.Details_ID <= a.Details_ID
GROUP BY a.Details_ID, a.Creation_Date, a.Reference_ID, a.Transaction_Kind,
a.Amount_Debit, a.Amount_Credit
Order By a.Details_ID Desc