【问题标题】:Updating a column using values from a Lookup table使用查找表中的值更新列
【发布时间】:2014-09-09 04:48:25
【问题描述】:

我在表 products 中有一个产品列表。这可能包含超过 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,则应将其解释为任何东西。

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

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 中有两个整体。 prod_type = 3 用于特定的 prod_region 'R1' 和 prod_type = 1 用于其余区域。 因此,products 中的前两条记录应分别为 1 和 3。
  2. 对于 prod_code 1002、1003,product_type 表中没有指定 prod_region。因此,无论 prod_region 是什么,都会为第三和第四条记录分配 prod_type = 2。

由于 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 特定答案。

【问题讨论】:

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


    【解决方案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;
    

    【讨论】:

      【解决方案2】:

      这样的事情怎么样:

      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
                  )
              )
          )
      )
      

      尽管有人可能会质疑像这样对数据进行非规范化的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多