我有一个名为wallet
的表,它记录所有钱包交易。假设用户可以通过4种方式向钱包添加资金,即credit_src1,credit_src2,credit_src3,credit_src4
,我有各自的列。此外,用户可以从他们的帐户中扣款,因此我有一个与之对应的列。
信用卡或借记卡的每笔交易都记录在具有相应交易ID的表中。用户只能对事务ID执行一次操作。
当用户从钱包借记时,我想检索每个信用来源中剩余的相应金额。假设从每个来源平均扣除金额。如果金额在一列中达到0,则会从剩余列中平均扣除,直到达到0。
这是源表:
ID src1 src2 src3 src4 debit
==========================================
1 10 0 0 0 0
2 10 0 0 0 0
3 0 50 0 0 0
4 0 0 40 0 0
5 0 0 0 0 30
6 0 0 0 0 70
目的地表应该是所有来源的累积总和减去每个来源的相等借方:
ID src1 src2 src3 src4 debit
==========================================
1 10 0 0 0 0
2 20 0 0 0 0
3 20 50 0 0 0
4 20 50 40 0 0
5 10 40 30 0 30
6 0 20 10 0 70
我可以使用此查询从各种来源获得一笔钱
SELECT
SUM(src1) OVER (ORDER BY ID),
SUM(src2) OVER (ORDER BY ID),
SUM(src3) OVER (ORDER BY ID),
SUM(src1) OVER (ORDER BY ID)
FROM wallet
我无法弄清楚如何在所有来源之间平均分配借记金额。任何形式的帮助将不胜感激。
答案 0 :(得分:2)
BigQuery及其BQL非常强大,可以克服一些评论中提到的限制问题!至少在某些情况下喜欢这个。所以...
以下是您正在寻找的内容。 使用JS UDF
完全在BigQuery中SELECT id, src1, src2, src3, src4, debit FROM JS(
// input table
(
SELECT GROUP_CONCAT(tx) AS txs
FROM (
SELECT CONCAT(STRING(id), '|' , STRING(src1), '|' ,
STRING(src2), '|' , STRING(src3), '|' ,
STRING(src4), '|' , STRING(debit)
) AS tx
FROM wallet
ORDER BY id
)
) ,
// input columns
txs,
// output schema
"[
{name: 'id', type: 'integer'},
{name: 'src1', type: 'integer'},
{name: 'src2', type: 'integer'},
{name: 'src3', type: 'integer'},
{name: 'src4', type: 'integer'},
{name: 'debit', type: 'integer'}
]",
// function
"function(r, emit){
var tx_list = r.txs.split(',');
var src1_total = 0;
var src2_total = 0;
var src3_total = 0;
var src4_total = 0;
var id = 0;
var debit = 0;
var cut = 0;
for (var i = 0; i < tx_list.length; i ++){
var src = tx_list[i].split('|');
id = parseInt(src[0]);
src1_total += parseInt(src[1]);
src2_total += parseInt(src[2]);
src3_total += parseInt(src[3]);
src4_total += parseInt(src[4]);
debit = parseInt(src[5]);
cut = debit;
while (cut > 0) {
if (src1_total > 0 && cut > 0) {src1_total--; cut--;}
if (src2_total > 0 && cut > 0) {src2_total--; cut--;}
if (src3_total > 0 && cut > 0) {src3_total--; cut--;}
if (src4_total > 0 && cut > 0) {src4_total--; cut--;}
}
emit({
id: id, src1: src1_total, src2: src2_total,
src3: src3_total, src4: src4_total, debit: debit
});
}
}"
)
输出:
id src1 src2 src3 src4 debit
1 10 0 0 0 0
2 20 0 0 0 0
3 20 50 0 0 0
4 20 50 40 0 0
5 10 40 30 0 30
6 0 10 0 0 70
请注意:以上解决方案不够灵活。取决于您的桌子(钱包)的大小(行数),您迟早会看到它。并密切关注生产层,因为随着行的增长它可能会变高。
我的建议:万一你要提到上面提到的限制 - 你应该编写类似于你在你选择的客户端上看到的udf代码的逻辑