使用 SQL 从贷方和 运行 余额中有条件地借记
Conditional debit from credits and running balance using SQL
我在 table cryptotransactionledger
中有如下数据
id
transaction_typeid
transaction_type
amount
totalcoins
1
1
bitcoin-credit
30
30
2
2
ethereum-credit
20
50
如果我花比特币,我会在相同的 table 和 transaction_typeid 3 中放置一个新条目,如下所示,类似地,对于以太坊, transaction_typeid 4
id
transaction_typeid
transaction_type
amount
totalcoins
1
1
bitcoin-credit
30
30
2
2
etherium-credit
20
50
3
3
bitcoin-debit
-10
40
4
4
etherium-debit
-5
35
假设如果我在 table 中的最终数据如下所示,我将有 35 个比特币和 20 个以太坊。
id
transaction_typeid
transaction_type
amount
totalcoins
1
1
bitcoin-credit
30
30
2
2
etherium-credit
20
50
3
3
bitcoin-debit
-10
40
4
4
etherium-debit
-5
35
5
1
bitcoin-credit
15
50
6
2
etherium-credit
10
60
7
4
etherium-debit
-5
55
在从相应的贷方中减少所有借方后,如何使用 SQL 得出低于余额的摘要
id
transaction_type
amount
totalcoins
1
bitcoin-credit
35
35
2
etherium-credit
20
55
假设您有表 ledger
和 coin_types
:
create table ledger (id varchar2(3) primary key,
coin_type varchar2(2),
amount number(5)
);
create table coin_types (id varchar2(2) primary key,
alias varchar2(100));
这些 DML 语句代表您的“最终数据”:
insert into coin_types values (1, 'bitcoin');
insert into coin_types values (2, 'etherium');
insert into ledger values (1, 1, 30);
insert into ledger values (2, 2, 20);
insert into ledger values (3, 1, -10);
insert into ledger values (4, 2, -5);
insert into ledger values (5, 1, 15);
insert into ledger values (6, 2, 10);
insert into ledger values (7, 2, -5);
您的第一步应该是汇总金额,按您的硬币类型分组:
select l.coin_type,
c.alias,
sum(l.amount) amount_coin
from ledger l, coin_types c
where l.coin_type = c.id
group by l.coin_type, c.alias
然后您可以使用此 select 获得您的“totalcoins”作为累积总和,按您的 coin_type (see Oraclee Docs):
排序
select coin_type,
alias,
amount_coin,
sum(amount_coin) over (order by coin_type) totalcoins
from(
select l.coin_type,
c.alias,
sum(l.amount) amount_coin
from ledger l, coin_types c
where l.coin_type = c.id
group by l.coin_type, c.alias
);
这是一个有效的 SQL-Fiddle:SQL-Fiddle
我会忘记最终结果的“交易类型”,只关注硬币本身。您的数据模型很奇怪,因为您没有单独的硬币类型列。但是您可以从 transaction_type
列中提取它。
此外,您的评论表明 totalcoins
应该是列中的最后一个值。 “比特币”是 50,而不是 35。
无论如何,您都可以使用聚合。我会建议:
select regexp_substr(transaction_type, '^[^-]+') as coin,
sum(amount) as amount,
max(totalcoins) keep (dense_rank first oder by id desc) as totalcoins
from cryptotransactionledger tl
group by regexp_substr(transaction_type, '^[^-]+');
Here 是一个 db<>fiddle.
我会创建一个 table 的 tran 类型
create table tran_types (
id int primary key,
coin_Name varchar2(100),
op_Name varchar2(100)
);
insert into tran_types
select 1, 'bitcoin', 'credit' from dual union all
select 2, 'etherium','credit' from dual union all
select 3, 'bitcoin', 'debit' from dual union all
select 4, 'etherium','debit' from dual;
通过这种方式,您可以对交易进行分组以获得总计,并根据需要可视化总计行headers
select t.id transaction_typeid, t.coin_Name || '-' || t.op_Name transaction_type,
s.amount, s.total_coins
from (
select t.coin_Name, sum(amount) amount
, sum(sum(amount)) over(order by t.coin_Name) total_coins
from ledger r
join tran_types t on r.tran_type = t.id
group by t.coin_Name
) s
join tran_types t on t.op_name = 'credit' and t.coin_Name = s.coin_Name
order by t.coin_Name;
感谢所有提出建议和不同解决方案的人。
我终于使用了下面的查询,它为我提供了预期的结果。
WITH cte1
AS (SELECT a.*,
CASE
WHEN ( transaction_typeid = 1
OR transaction_typeid = 3 ) THEN 0
ELSE 1
END AS category
FROM cryptotransactionledger a
ORDER BY id),
cte2
AS (SELECT CASE
WHEN ( category = 0 ) THEN 'bitcoin-credit'
ELSE 'etherium-credit'
END AS transaction_type,
Sum(amount) AS amount
FROM cte1 o
GROUP BY category),
cte3
AS (SELECT Row_number()
OVER (ORDER BY c.transaction_type) AS id,
c.*
FROM cte2 c) SELECT f.*,
Sum(amount) OVER(ORDER BY f.id) AS total_coins FROM cte3 f;
我在 table cryptotransactionledger
中有如下数据id | transaction_typeid | transaction_type | amount | totalcoins |
---|---|---|---|---|
1 | 1 | bitcoin-credit | 30 | 30 |
2 | 2 | ethereum-credit | 20 | 50 |
如果我花比特币,我会在相同的 table 和 transaction_typeid 3 中放置一个新条目,如下所示,类似地,对于以太坊, transaction_typeid 4
id | transaction_typeid | transaction_type | amount | totalcoins |
---|---|---|---|---|
1 | 1 | bitcoin-credit | 30 | 30 |
2 | 2 | etherium-credit | 20 | 50 |
3 | 3 | bitcoin-debit | -10 | 40 |
4 | 4 | etherium-debit | -5 | 35 |
假设如果我在 table 中的最终数据如下所示,我将有 35 个比特币和 20 个以太坊。
id | transaction_typeid | transaction_type | amount | totalcoins |
---|---|---|---|---|
1 | 1 | bitcoin-credit | 30 | 30 |
2 | 2 | etherium-credit | 20 | 50 |
3 | 3 | bitcoin-debit | -10 | 40 |
4 | 4 | etherium-debit | -5 | 35 |
5 | 1 | bitcoin-credit | 15 | 50 |
6 | 2 | etherium-credit | 10 | 60 |
7 | 4 | etherium-debit | -5 | 55 |
在从相应的贷方中减少所有借方后,如何使用 SQL 得出低于余额的摘要
id | transaction_type | amount | totalcoins |
---|---|---|---|
1 | bitcoin-credit | 35 | 35 |
2 | etherium-credit | 20 | 55 |
假设您有表 ledger
和 coin_types
:
create table ledger (id varchar2(3) primary key,
coin_type varchar2(2),
amount number(5)
);
create table coin_types (id varchar2(2) primary key,
alias varchar2(100));
这些 DML 语句代表您的“最终数据”:
insert into coin_types values (1, 'bitcoin');
insert into coin_types values (2, 'etherium');
insert into ledger values (1, 1, 30);
insert into ledger values (2, 2, 20);
insert into ledger values (3, 1, -10);
insert into ledger values (4, 2, -5);
insert into ledger values (5, 1, 15);
insert into ledger values (6, 2, 10);
insert into ledger values (7, 2, -5);
您的第一步应该是汇总金额,按您的硬币类型分组:
select l.coin_type,
c.alias,
sum(l.amount) amount_coin
from ledger l, coin_types c
where l.coin_type = c.id
group by l.coin_type, c.alias
然后您可以使用此 select 获得您的“totalcoins”作为累积总和,按您的 coin_type (see Oraclee Docs):
排序 select coin_type,
alias,
amount_coin,
sum(amount_coin) over (order by coin_type) totalcoins
from(
select l.coin_type,
c.alias,
sum(l.amount) amount_coin
from ledger l, coin_types c
where l.coin_type = c.id
group by l.coin_type, c.alias
);
这是一个有效的 SQL-Fiddle:SQL-Fiddle
我会忘记最终结果的“交易类型”,只关注硬币本身。您的数据模型很奇怪,因为您没有单独的硬币类型列。但是您可以从 transaction_type
列中提取它。
此外,您的评论表明 totalcoins
应该是列中的最后一个值。 “比特币”是 50,而不是 35。
无论如何,您都可以使用聚合。我会建议:
select regexp_substr(transaction_type, '^[^-]+') as coin,
sum(amount) as amount,
max(totalcoins) keep (dense_rank first oder by id desc) as totalcoins
from cryptotransactionledger tl
group by regexp_substr(transaction_type, '^[^-]+');
Here 是一个 db<>fiddle.
我会创建一个 table 的 tran 类型
create table tran_types (
id int primary key,
coin_Name varchar2(100),
op_Name varchar2(100)
);
insert into tran_types
select 1, 'bitcoin', 'credit' from dual union all
select 2, 'etherium','credit' from dual union all
select 3, 'bitcoin', 'debit' from dual union all
select 4, 'etherium','debit' from dual;
通过这种方式,您可以对交易进行分组以获得总计,并根据需要可视化总计行headers
select t.id transaction_typeid, t.coin_Name || '-' || t.op_Name transaction_type,
s.amount, s.total_coins
from (
select t.coin_Name, sum(amount) amount
, sum(sum(amount)) over(order by t.coin_Name) total_coins
from ledger r
join tran_types t on r.tran_type = t.id
group by t.coin_Name
) s
join tran_types t on t.op_name = 'credit' and t.coin_Name = s.coin_Name
order by t.coin_Name;
感谢所有提出建议和不同解决方案的人。 我终于使用了下面的查询,它为我提供了预期的结果。
WITH cte1
AS (SELECT a.*,
CASE
WHEN ( transaction_typeid = 1
OR transaction_typeid = 3 ) THEN 0
ELSE 1
END AS category
FROM cryptotransactionledger a
ORDER BY id),
cte2
AS (SELECT CASE
WHEN ( category = 0 ) THEN 'bitcoin-credit'
ELSE 'etherium-credit'
END AS transaction_type,
Sum(amount) AS amount
FROM cte1 o
GROUP BY category),
cte3
AS (SELECT Row_number()
OVER (ORDER BY c.transaction_type) AS id,
c.*
FROM cte2 c) SELECT f.*,
Sum(amount) OVER(ORDER BY f.id) AS total_coins FROM cte3 f;