0

将已作废的收据与原始收据匹配:

我有一个transaction看起来像这样的表:

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

每张收据/购买都是transaction_start和的组合store_no。每张收据可以有一个或多个(以及由变量item_no给出的相应价格)。amount如果收据有两个或更多项目,则重复transaction_start和值。store_no所以在上表中,总共可以观察到 7 个收据:收据 1 由transaction_start= '2021-02-28 08:00:00' 和store_no= '001' 给出,包含以下项目:101、105 和 109 ; 收据 2 by transaction_start= '2021-03-01 10:00:00' and store_no= '001',包含以下项目:101、105 和 109,依此类推。

最后一张收据(transaction_start='2021-03-01 10:11:00' and store_no='001')是第二张收据(transaction_start='2021-03-01 10:00:00' and store_no=' 001')无效的帖子)。后作废指示由列和值post_voided= 'Y' 给出。

我的目标是更改原始日期transaction_start时间的post_voided= 'Y' 收据。transaction_start原始收据是指所有item_no和(负)amount来自后作废收据(即post_voided= 'Y')必须与最接近的(即相等或更低)transaction_start、包含相同、(正)store_no的收据匹配,而不是后作废( oe = 'N')。item_noamountpost_voided

期望的输出:

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

这里是表格的链接:https ://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=06afe841d89c4ecbf600436433cd1c5d

提前致谢!

4

1 回答 1

1

试试下面

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)   

如果应用于有问题的样本 - 输出是。

在此处输入图像描述

于 2021-03-27T21:21:23.513 回答