Oracle更新列,其中包含来自同一表的最大值和列

时间:2016-12-13 17:28:18

标签: sql oracle

我必须在同一个表上更新具有最大值的多个列。伪查询将类似于 -

UPDATE PERMIT 
SET P_ID = 'FIRST FIVE CHARACTERS WILL REMAIN SAME AND LAST few WILL BE REPLACED BY SELECT Max(prmt_appl_sq) FROM PERMIT SOME CONDITION',
prmt_appl_sq = 'AND NOW UPDATE WITH SAME MAX VALUE USED ABOVE'
WHERE 
CONDITION

表数据就像 P_ID P_APPL_SQ CCode 2016-H-193-5 10 193 列P_ID有一个唯一的约束,最后一部分*** - 5实际上是P_APPL_SQ中的值,每次创建具有相同的其他三个值的记录时,它们会递增。 例如,当创建具有2016年年级并且键入-H和中心193的新记录时,P_ID将变为******** - 6。我必须更新所有CCode = 193到195的记录,并将p_ID更新为2016-H-195-“前三个组合的MAX值+1”,然后更新P_APPL_SQ的值相同。

我提出了查询,但它尝试在每一行上添加相同的值,从而抛出唯一的约束违规     更新OSPDBA.OSPT001_PRMT_APPL
      SET rted_to_org_cd ='55014040191',       PRMT_ID = SUBSTR(PRMT_ID,0,11)|| (SELECT Max(prmt_appl_sq)+ 1 FROM     OSPDBA.OSPT001_PRMT_APPL其中rted_to_org_cd ='55014040191'和prmt_sbmt_yr     = 2016和prmt_typ_cd ='H'),       prmt_appl_sq =((SELECT Max(prmt_appl_sq)+ 1 FROM OSPDBA.OSPT001_PRMT_APPL     其中rt_to_org_cd ='55014040191'和prmt_sbmt_yr = 2016和prmt_typ_cd =     'H'))     哪里        rt_to_org_cd IN('55014040193','55014040195')和prmt_sbmt_yr = 2016;

我们如何为每条记录提供唯一的最大值?

3 个答案:

答案 0 :(得分:0)

可以在单个查询中完成,没问题。更接近实际查询的伪查询将是

UPDATE PERMIT 
SET P_ID = substr(p_id, 0, 5) || (SELECT Max(prmt_appl_sq) FROM PERMIT SOME CONDITION),
prmt_appl_sq = (SELECT Max(prmt_appl_sq) FROM PERMIT SOME CONDITION)
WHERE 
CONDITION

条件必须设计得很好,如果PERMIT足够大,你可能会遇到性能问题。

=============================================== ======

更新了查询

UPDATE OSPDBA.OSPT001_PRMT_APPL a 

SET rted_to_org_cd = '55014040191', 

PRMT_ID = SUBSTR(PRMT_ID, 0, 11) || (SELECT Max(prmt_appl_sq) + 1 FROM OSPDBA.OSPT001_PRMT_APPL b where a.rted_to_org_cd = b.rted_to_org_cd and prmt_sbmt_yr = 2016 and prmt_typ_cd = 'H'), 

prmt_appl_sq = (SELECT Max(prmt_appl_sq) + 1 FROM OSPDBA.OSPT001_PRMT_APPL c where a.rted_to_org_cd = c.rted_to_org_cd and prmt_sbmt_yr = 2016 and prmt_typ_cd = 'H') 

WHERE rted_to_org_cd IN ('55014040193','55014040195') and prmt_sbmt_yr = 2016;

答案 1 :(得分:0)

尝试此查询:

index.md

答案 2 :(得分:0)

我必须编写一个光标来进行批量更新。

    DECLARE
    C_PRMT_SQ                   PRMT_APPL.PRMT_SQ%TYPE; 
    C_PRMT_SBMT_YR              PRMT_APPL.PRMT_SBMT_YR%TYPE;    
    MAX_APPL_SEQ                PRMT_APPL.PRMT_APPL_SQ%TYPE;    

    L_ERR_LEVEL                 NUMBER := 0;
    MAX_SEQ_VAL                 VARCHAR2(220);


    -- SELECT ALL PERMITS OF PURGED CC FROM THE DATABASE
    CURSOR CSEQUENCE IS
        SELECT PRMT_SQ,PRMT_SBMT_YR FROM PRMT_APPL 
        WHERE RTED_TO_ORG_CD IN ('55014040193','55014040195') ORDER BY PRMT_SBMT_YR DESC;
-- MAIN 
BEGIN
    OPEN CSEQUENCE; 
    L_ERR_LEVEL := 1;

    LOOP

    FETCH CSEQUENCE INTO C_PRMT_SQ,C_PRMT_SBMT_YR;

    DBMS_OUTPUT.PUT_LINE ('C_PRMT_SQ ' || TO_CHAR(C_PRMT_SQ) || '  '  || TO_CHAR(C_PRMT_SBMT_YR));

    EXIT WHEN CSEQUENCE%NOTFOUND;

    SELECT (MAX(PRMT_APPL_SQ) + 1) INTO MAX_APPL_SEQ FROM PRMT_APPL WHERE  RTED_TO_ORG_CD = '55014040191' AND PRMT_SBMT_YR = C_PRMT_SBMT_YR AND PRMT_TYP_CD = 'H'; 

    MAX_SEQ_VAL := 'MAX_APPL_SEQ ' || TO_CHAR(MAX_APPL_SEQ); 

    DBMS_OUTPUT.PUT_LINE (MAX_SEQ_VAL);

    UPDATE PRMT_APPL  
        SET   
            RTED_TO_ORG_CD = '55014040191',
            PRMT_ID = SUBSTR(PRMT_ID, 0, 7) || 191 || '-' || MAX_APPL_SEQ,
            PRMT_APPL_SQ = MAX_APPL_SEQ,
            UPDT_TMS = SYSTIMESTAMP
        WHERE   PRMT_SQ = C_PRMT_SQ;

    COMMIT;

    END LOOP;
    CLOSE CSEQUENCE;    
    L_ERR_LEVEL := 3;
END;