一周前我问过以下问题:
Compare Rows in oracle table and update matching ones
我收到了非常有用的答案,但我再次陷入困境,因为我需要修改收到的答案,并添加另一个过滤器。
除了具有不同的BuySell字段之外,还有一个不能相等的Description字段。 与只能采用两个值的BuySell字段不同,描述可以是任何值。
以下是我一直在使用的@ MT0的答案,我希望修改:
MERGE INTO your_table dst
USING ( SELECT ROW_NUMBER() OVER (
PARTITION BY tDate, Product, Price, Quantity, BuySell
ORDER BY ID
) AS idx,
COUNT( CASE BuySell WHEN 'Buy' THEN 1 END ) OVER (
PARTITION BY tDate, Product, Price, Quantity
) AS num_buy,
COUNT( CASE BuySell WHEN 'Sell' THEN 1 END ) OVER (
PARTITION BY tDate, Product, Price, Quantity
) AS num_sell FROM your_table
) src ON ( src.ROWID = dst.ROWID AND src.idx <= LEAST( src.num_buy, src.num_sell ) )
WHEN MATCHED THEN UPDATE SET Status = 'Matched';
编辑: 以下是一个例子
我有一张如下表:
**ID tDate Product Description Price Quantity BuySell Status**
1 10-May-17 pppp p1 $12 20 Buy Null
2 12-May-17 tttt t1 $10 20 Sell Null
3 12-May-17 tttt t2 $10 20 Buy Null
4 18-May-17 pppp p2 $14 20 Sell Null
5 18-May-17 pppp p3 $14 20 Buy Null
6 19-May-17 xxxx x4 $11 10 Sell Null
7 19-May-17 xxxx x4 $11 10 Buy Null
我需要更新名为STATUS的字段,并将其设置为“匹配”,只要找到一个具有相同tDate,产品,价格和数量且不等于BuySell AND Description的对。
以下是期望的结果:
**ID tDate Product Description Price Quantity BuySell Status**
1 10-May-17 pppp p1 $12 20 Buy Null
2 12-May-17 tttt t1 $10 20 Sell Matched
3 12-May-17 tttt t2 $10 20 Buy Matched
4 18-May-17 pppp p2 $14 20 Sell Matched
5 18-May-17 pppp p3 $14 20 Buy Matched
6 19-May-17 xxxx x4 $11 10 Sell Null
7 19-May-17 xxxx x4 $11 10 Buy Null
请注意,6和7不匹配,因为它们具有相同的描述。
答案 0 :(得分:0)
update your_table
set status='Matched'
where id in(
with IDS(id1,id2,grp,num,rnum) as(
select a.id,b.id,
rank() over(order by a.tdate,a.price,a.product,a.quantity),
case when a.id=lag(a.id) over(partition by a.tdate,a.price,a.product,a.quantity order by a.id)
then 0
else dense_rank() over(partition by a.tdate,a.price,a.product,a.quantity order by a.id) end,
row_number() over(partition by a.tdate,a.price,a.product,a.quantity order by a.id)
from your_table a, your_table b
where a.tdate=b.tdate and a.price=b.price and a.product=b.product
and a.quantity=b.quantity
and a.buysell='Sell' and b.buysell='Buy' and a.description!=b.description
),
Q(id1,id2,grp,num,used) as(
select id1,id2,grp,num,','||id2||','
from IDS where rnum=1
union all
select I.id1,R.column_value,Q.grp,Q.num+1,Q.used||R.column_value||','
from Q, IDS I,
table(cast(multiset(
select min(id2) id from IDS N
where N.id1=I.id1
and Q.used not like '%,'||N.id2||',%'
) as sys.ODCINumberList)) R
where I.grp=Q.grp and I.num=Q.num+1
)
select decode(X,1,id1,id2)
from Q,
(select 1 X from DUAL union all select 2 from DUAL)
where id2 is not null
)