在Oracle PLSQL中插入上一条记录中金额为负的重复行

yfwxisqw  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(104)

我有一个要求,我们需要创建相同的一组行,等于表中已经存在的行数,然后更新金额。基本上,我们希望在able中创建两组相同的行,其中唯一的区别是正数和负数,类似于下表。我需要为表中已经存在的每个正数行生成负数行。
这就是最终产品应该是什么样子:

我如何才能做到这一点?当前表中只有正数行。在上面的示例图像中,我尝试基于奇数和偶数行ID进行验证,但这也意味着首先使用偶数更新预先存在的正数行,然后将行ID递增为负数。但这对我也不起作用。
请告知实现这一目标的最佳方式。下面是示例数据

注意,表中只有正数行,我们需要添加负数行。对于每个正金额行,必须为相同金额创建负金额行

CREATE TABLE XXRR_LINE_STG 
   (    DOCUMENT_ID NUMBER, 
    LINE_ID NUMBER, 
    LINE_VALUE NUMBER
   ) ;

REM INSERTING into PROCORE_WH_DATA.XXRR_LINE_STG
SET DEFINE OFF;
Insert into XXRR_LINE_STG (DOCUMENT_ID,LINE_ID,LINE_VALUE) values (543210,1,211.75);
Insert into XXRR_LINE_STG (DOCUMENT_ID,LINE_ID,LINE_VALUE) values (543210,2,311.75);
Insert into XXRR_LINE_STG (DOCUMENT_ID,LINE_ID,LINE_VALUE) values (543210,3,411.75);

救命啊!!
感谢Darsh

hgtggwj0

hgtggwj01#

你可以做一些像UNION ALL这样简单的操作来添加新行,然后重构行id:

SELECT document_id,
       ROW_NUMBER() OVER (PARTITION BY document_id ORDER BY line_id) line_id,
       line_value
  FROM (SELECT document_id,
               line_id,
               line_value
          FROM xxrr_line_stg
        UNION ALL
        SELECT document_id,
               lineid+0.5 line_id,
               -line_value
          FROM xxrr_line_stg
         WHERE line_value > 0)

或者更紧凑一点(也更难理解一点),创建一个连接到伪行的额外行:

SELECT document_id,
       ROW_NUMBER() OVER (PARTITION BY document_id ORDER BY line_id,seq) line_id,
       DECODE(seq,1,line_value,-line_value) line_value
  FROM xxrr_line_stg,
       (SELECT LEVEL seq FROM dual CONNECT BY LEVEL <= 2)
 WHERE seq <= CASE WHEN (stg.line_value > 0) THEN 2 ELSE 1 END
mdfafbf1

mdfafbf12#

如果你想在表中插入新数据,可以使用MERGE语句:

MERGE INTO xxrr_line_stg dst
USING xxrr_line_stg src
ON (   dst.document_id = src.document_id
   AND dst.line_id     = src.line_id
   AND dst.line_value  = -src.line_value
   AND src.line_value  > 0
   )
WHEN NOT MATCHED THEN
  INSERT (document_id, line_id, line_value)
  VALUES (src.document_id, src.line_id, -src.line_value);

然后在MERGE之后,您的表将包含:
| 文件ID| LINE_ID|线值|
| --|--|--|
| 543210 | 1 |二百一十一点七五|
| 543210 | 1 | -211.75 |
| 543210 | 2 |三百一十一点七五|
| 543210 | 2 | -311.75 |
| 543210 | 3 |四百一十一点七五|
| 543210 | 3 | -411.75 |
如果你然后INSERT一个新的行到表中,并希望添加缺失的负值,那么你可以再次运行MERGE语句,它将只INSERT缺失的负值。
如果表中的值可以更改,并且您希望重新同步正数和负数,则可以使用:用途:

MERGE INTO xxrr_line_stg dst
USING (
  SELECT *
  FROM   xxrr_line_stg
  WHERE  line_value > 0
) src
ON (   dst.document_id = src.document_id
   AND dst.line_id     = src.line_id
   AND dst.ROWID       != src.ROWID
   )
WHEN MATCHED THEN
  UPDATE
  SET    dst.line_value = -src.line_value
  WHERE  dst.line_value < 0
  AND    dst.line_value != -src.line_value
WHEN NOT MATCHED THEN
  INSERT (document_id, line_id, line_value)
  VALUES (src.document_id, src.line_id, -src.line_value);

fiddle

相关问题