Google bigquery 将过账作废收据的交易开始与原始收据的交易开始匹配

Google bigquery 将过账作废收据的交易开始与原始收据的交易开始匹配,google-bigquery,Google Bigquery,将过账作废收据与原始收据匹配: 我有一个事务表,如下所示: transaction_start store_no item_no amount post_voided 2021-02-28 08:00:00 001 101 45 N 2021-02-28 08:00:00 001 105

将过账作废收据与原始收据匹配:

我有一个
事务
表,如下所示:

transaction_start        store_no        item_no        amount        post_voided
2021-02-28 08:00:00           001            101            45                  N
2021-02-28 08:00:00           001            105            25                  N
2021-02-28 08:00:00           001            109            40                  N
2021-03-01 10:00:00           001            101            45                  N
2021-03-01 10:00:00           001            105            25                  N
2021-03-01 10:00:00           001            109            40                  N
2021-03-01 10:02:00           002            101            45                  N
2021-03-01 10:02:00           002            105            25                  N
2021-03-01 10:02:00           002            109            40                  N
2021-03-01 10:04:00           001            101            45                  N
2021-03-01 10:05:00           002            103            35                  N
2021-03-01 10:05:00           002            135            20                  N
2021-03-01 10:08:00           001            140            2                   N
2021-03-01 10:11:00           001            101           -45                  Y
2021-03-01 10:11:00           001            105           -25                  Y
2021-03-01 10:11:00           001            109           -40                  Y
每个收货/采购都是
交易开始
门店号
的组合。每个收据可以有一个或多个
项目编号
(以及
金额
变量给出的相应价格)。如果收据有两个或多个项目,则重复
交易开始
存储
值。因此,在上表中,总共可以观察到7张收据:收据1由
交易开始
='2021-02-28 08:00:00'和
商店编号
='001'给出,包含以下项目:101、105和109;由
交易开始的收据2
='2021-03-01 10:00:00'和
门店号>/code>='001',包含以下项目:101、105和109,依此类推

最后一张收据(
transaction\u start
=“2021-03-01 10:11:00”和
store\u no
=“001”)是第二张收据(
transaction\u start
=“2021-03-01 10:00:00”和
store\u no
=“001”)的后作废。后作废指示由列和值
post\u void
=“Y”给出

我的目标是更改原始
交易开始日期时间的
后作废的
='Y'收据的
交易开始日期。通过原始收据,意味着从后作废收据(即
后作废
=“Y”)中获得的所有
项目编号
和(负)
金额
(即
后作废
=“Y”)必须与最近的(即相等或更低的)
交易开始
存储编号
收据(包含相同的
项目编号
,(正)
金额
且未后期作废(即
后期作废
='N')

期望输出:

transaction_start        store_no        item_no        amount        post_voided
2021-02-28 08:00:00           001            101            45                  N
2021-02-28 08:00:00           001            105            25                  N
2021-02-28 08:00:00           001            109            40                  N
2021-03-01 10:00:00           001            101            45                  N
2021-03-01 10:00:00           001            105            25                  N
2021-03-01 10:00:00           001            109            40                  N
2021-03-01 10:02:00           002            101            45                  N
2021-03-01 10:02:00           002            105            25                  N
2021-03-01 10:02:00           002            109            40                  N
2021-03-01 10:04:00           001            101            45                  N
2021-03-01 10:05:00           002            103            35                  N
2021-03-01 10:05:00           002            135            20                  N
2021-03-01 10:08:00           001            140            2                   N
2021-03-01 10:00:00           001            101           -45                  Y
2021-03-01 10:00:00           001            105           -25                  Y
2021-03-01 10:00:00           001            109           -40                  Y
以下是表格的链接:

提前谢谢

试试下面

with receipts as (
  select transaction_start, store_no, post_voided, 
    format('%t', array_agg(struct(item_no, abs(amount) as amount) order by item_no)) receipt_hash
  from `project.dataset.table`
  group by transaction_start, store_no, post_voided
), last_receipts as ( 
  select any_value(y).*, 
    max(n.transaction_start) last_transaction_start,
  from receipts y
  join receipts n
  on y.transaction_start >= n.transaction_start
  and y.store_no = n.store_no
  and y.receipt_hash = n.receipt_hash
  where y.post_voided = 'Y' and n.post_voided = 'N'
  group by format('%t', y)
)
select a.* 
  replace(if(a.post_voided = 'N', transaction_start, last_transaction_start) as transaction_start)
from `project.dataset.table` a
left join last_receipts
using(transaction_start, store_no)   
如果应用于有问题的样本,则输出为