Oracle Query:单个更新语句

时间:2014-05-22 12:23:12

标签: oracle plsql

我需要为以下逻辑编写Oracle Query代码,并且感谢任何帮助。

我有一个包含8列的表,其中需要考虑3列用于特定的业务逻辑。

表数据(3列)

A               B             C 

071699          01            I

071699          01W     

071699          02W     

071699          01W           I

071699          02W     

更多行。

数据量因具体情况而异,这意味着每列A-B组合可能有一行或多行,通常不在这些行中 列C填充至少1个组合。

此表具有超过100K的不同A值。

逻辑我需要实现:

  1. 检查 - 具体A值,我们有多少组合(A-B)。 对于特定的A:检查是否使用C列数据填充了任何组合(A-B)。
  2. 从填充的C列中获取值并更新同一个表(对于相同A的其他组合)
  3. 之前的数据(仅显示特定行)

    A               B             C 
    
    071699          01            I
    
    071699          01W     
    
    071699          02W     
    

    查询后的数据

    A               B             C  
    
    071699          01            I
    
    071699          01W           I
    
    071699          02W           I
    

    我有一个SQL服务器查询在一个查询中执行此逻辑但在Oracle中无法运行,我收到错误,"单行查询返回多行"

    SQL Server查询

    update c 
    set c.colC = u.colC
    from data_table u
    join data_table c on u.colA = c.colA and u.colB <> c.colB
        and u.colB = (select MIN(colB) from data_table  
                        where colA = u.colA and colC is not    null)
    and u.colC is not null and c.colC is null
    

    任何帮助都可以写出类似的oracle版本。

3 个答案:

答案 0 :(得分:0)

Oracle不允许在更新查询中加入,除非您有一个唯一的列,该列保证1-1映射在您的情况下绝对不适用。所以你可以在这里做的最好的是一个嵌套的子查询。它不是很漂亮,但它会起作用。我无法将您需要实现的逻辑与SQL Server更新语句中的逻辑完全匹配,因此我接着使用了该语句。

UPDATE data_table u
SET u.COLC =(
  SELECT  c.ColC
  FROM    data_table c
  WHERE   c.ColA = u.ColA
    and   c.ColB =(
        SELECT  MIN( ColB )
        FROM    data_table
        WHERE   ColA = c.ColA
          AND   ColC IS NOT NULL
      )
)
where u.ColC is null;

答案 1 :(得分:0)

我尝试了在单个查询中执行此任务的各种方法,但由于Oracle的限制而无法实现此任务,以下是解决方案适用于我:

我将查询分为两部分 - 一部分执行insert语句,另一部分执行update。

  1. 第一个查询:这里我将行插入另一个临时表,逻辑 - 每个colA获取不同的行 - ColC,其中colC是polulated。

  2. 使用在步骤1中创建的tmp表,通过colA上的join连接来更新主数据表。

  3. 如果有人有更好的解决方案,那么请发送您的回复,我一定会尝试。

答案 2 :(得分:0)

我在尝试各种方法(如拆分为两个tmp表,游标等)之后使用基于集合的编码解决了这个问题,下面是示例代码:

此查询比任何其他解决方案快3-5倍。

   UPDATE data_table a SET C = (
        WITH comp AS (
        SELECT  DISTINCT A, C FROM data_table a 
        WHERE B = (SELECT MIN(B) FROM data_table
                              WHERE A =  a.A
                              AND C IS NOT NULL)
                    )
         SELECT 
            CASE
                when a.C IS NULL  THEN c.C
                when a.C IS NOT NULL THEN a.C
            END    
         FROM comp c 
         WHERE a.A = c.A AND c.C IS NOT NULL  
     );