【问题标题】:not able to "UPDATE SET WHERE" when I have to order with "order by case when当我必须使用“按情况订购时”订购时,无法“更新设置在哪里”
【发布时间】:2017-12-12 13:48:45
【问题描述】:

我有以下查询可以正常工作(请参阅我的其他帖子)。

SELECT sys_annot from ( 
         SELECT SYS_ANNOT, row_number() over (order by case when prep_seq_num = 0 then 1 else 2 end) as rn
         FROM  BILL
         WHERE BIMA_TRACKING_ID = 10
         AND   BSCO_CODE_ID = 'PINGPONG'
         AND   PARTITION_KEY = '06-DEC-17'
         AND   SUBPARTITION_KEY = 84
         AND
        (
          (  PREP_SEQ_NUM = 0
             AND ITEM_CAT_CODE_ID=1
             AND PRIMARY_IND=0
             AND CHRG_ACCT_ID = 1
             AND SYS_ANNOT <> 0
          )
        OR

          ( PREP_SEQ_NUM <> 0 
            AND ITEM_CAT_CODE_ID in ('5', '-100') 
            AND PRIMARY_IND=1
          )
        )
        )
        where rn=1
     ;

同时我现在想只在上面查询返回的单行中更新 sys_annot 字段的值为 100,即:

update BILL SET SYS_ANNOT=100
where ????

无论我尝试什么都行不通,请在这里提供帮助。 谢谢

【问题讨论】:

  • Oracle (在我个人看来) 使这比它需要的更难。其他方言允许UPDATE x SET y = x FROM &lt;some sub_query&gt; 以各种形式出现。我知道的唯一答案要么涉及临时保留表,要么(现在在下面的答案中出现)使用类似target_table.primary_key IN (some sub query)的东西。
  • 另外,当您说whatever I try 时,请展示您实际尝试过的内容。当您说does not work 时,请具体说明:错误消息(包括错误消息)、意外结果(显示您得到的结果以及您预期的结果)。

标签: sql oracle sql-update sql-order-by case


【解决方案1】:

您应该使用主键来识别行的唯一记录。在这种情况下,您可以使用 rowid(仅适用于 Oracle)。对于多行来说效率不是很高,但对于一行就足够了:

update BILL b SET SYS_ANNOT=100
where b.rowid in (
SELECT rid from ( 
         SELECT bill.rowid rid, SYS_ANNOT, row_number() over (order by case when prep_seq_num = 0 then 1 else 2 end) as rn
         FROM  BILL
         WHERE BIMA_TRACKING_ID = 10
         AND   BSCO_CODE_ID = 'PINGPONG'
         AND   PARTITION_KEY = '06-DEC-17'
         AND   SUBPARTITION_KEY = 84
         AND
        (
          (  PREP_SEQ_NUM = 0
             AND ITEM_CAT_CODE_ID=1
             AND PRIMARY_IND=0
             AND CHRG_ACCT_ID = 1
             AND SYS_ANNOT <> 0
          )
        OR

          ( PREP_SEQ_NUM <> 0 
            AND ITEM_CAT_CODE_ID in ('5', '-100') 
            AND PRIMARY_IND=1
          )
        )
        )
        where rn=1);

如果您确定只返回一行,则可以使用 = 代替 in

【讨论】:

    【解决方案2】:

    不确定我是否理解这个问题,但您不应该嵌套另一个语句吗?

    我的意思是你可以在开头添加update BILL SET SYS_ANNOT=100 where ????,比如:

    update BILL SET SYS_ANNOT=100
    where SYS_ANNOT = (SELECT sys_annot from ( 
             SELECT SYS_ANNOT, row_number() over (order by case when prep_seq_num = 0 then 1 else 2 end) as rn
             FROM  BILL
             WHERE BIMA_TRACKING_ID = 10
             AND   BSCO_CODE_ID = 'PINGPONG'
             AND   PARTITION_KEY = '06-DEC-17'
             AND   SUBPARTITION_KEY = 84
             AND
            (
              (  PREP_SEQ_NUM = 0
                 AND ITEM_CAT_CODE_ID=1
                 AND PRIMARY_IND=0
                 AND CHRG_ACCT_ID = 1
                 AND SYS_ANNOT <> 0
              )
            OR
    
              ( PREP_SEQ_NUM <> 0 
                AND ITEM_CAT_CODE_ID in ('5', '-100') 
                AND PRIMARY_IND=1
              )
            )
            )
            where rn=1
         );
    

    【讨论】:

    • 这个查询可以更新多条记录,而OP只需要一条。
    猜你喜欢
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多