使用Lookup表中的值更新列

时间:2014-07-18 06:17:31

标签: sql oracle sql-update teradata sql-merge

我在表格,产品中列出了产品。这可能包含超过500万条记录。

prod_code   prod_region     prod_desc       prod_type
------------------------------------------------------
1001        R2              r2 asdasa
1001        R1              r1 erfffv
1002        R4              r4 vfdser
1003        R2              r2 sdfdfv

prod_code和prod_region不可为空。

我需要更新此表中的prod_type,从另一个查找表product_type中选择。

prod_type   prod_code   prod_region
-----------------------------------
1           1001 
2           1002 
2           1003 
3           1001        R1

在此表中,prod_region可以为null。如果为null,则应将其解释为Anything。

所以我的更新产品表应该是,

prod_code   prod_region     prod_desc       prod_type
------------------------------------------------------
1001        R2              r2 asdasa       1       
1001        R1              r1 erfffv       3
1002        R4              r4 vfdser       2
1003        R2              r2 sdfdfv       2

所需输出的说明。

  1. 对于prod_code = 1001,product_type中有两个entires。 prod_type = 3表示特定prod_region'R1',prod_type = 1表示其余区域。 因此,产品中的前两个记录应分别获得1和3。
  2. 对于prod_code 1002,1003,product_type表中没有指定prod_region。因此,无论prod_region如何,第三和第四条记录都被分配了prod_type = 2。
  3. 由于Oracle中的ORA-30926: unable to get a stable set of rows in the source tables或Teradata中的Failure 7547 Target row updated by multiple source rows.,以下合并声明失败。

    merge into products
    using product_type
    on (products.prod_code = product_type.prod_code
        and products.prod_region = coalesce(product_type.prod_region,products.prod_region)
        )
    when matched then update
    set products.prod_type = product_type.prod_type;
    

    寻找标准的SQL或Teradata特定答案。

2 个答案:

答案 0 :(得分:1)

这样的事情怎么样:

update products
set prod_type = (
    select T.prod_type
    from product_type T
    where T.prod_code = products.prod_code
    and (
        T.prod_region = product.prod_region
        or (
            T.prod_region is null 
            and not exists (
                select 1 
                from product_type T2 
                where T2.prod_code = products.prod_code
                and T2.prod_region = product.prod_region
            )
        )
    )
)

虽然有人可能会质疑像这样对数据进行反规范化的原因。

答案 1 :(得分:1)

您可以将它拆分为两个简单的MERGE,而不是一个复杂的语句:

merge into products
using product_type
   on products.prod_code = product_type.prod_code
  and product_type.prod_region is null   
when matched then update
set prod_type = product_type.prod_type;

merge into products
using product_type
   on products.prod_code = product_type.prod_code
  and products.prod_region = product_type.prod_region
when matched then update
set prod_type = product_type.prod_type;