【问题标题】:Build dynamic query in oracle在 oracle 中构建动态查询
【发布时间】:2014-03-29 16:37:49
【问题描述】:

您能帮我构建如下查询吗?

TABLE_A

id   品牌颜色             尺寸      型号     yn_buy
1    A        蓝色            M           A            -
2    A         灰色             X          C              -
3    B         红色              X           B               -
4    C        蓝色             S         C             -

TABLE_B

品牌标准
A          颜色=灰色,尺寸=X
B          颜色=红色
C          大小=M


我想构建一个查询来更新表 A,答案应该是:

TABLE_A

id   品牌颜色             尺寸      型号     yn_buy
1    A        蓝色            M          A            N
2    A         灰色             X         C             Y
3    B         红色               X           B               Y
4   C       蓝色             S         C            N


如您所见,“标准”列上的数据应该是购买与否的决定因素

我想使用单个合并,如下所示

合并到 TABLE_A a
使用
(
选择 id、品牌、CASE WHEN critery THEN 'Y' ELSE 'N' END yn_buy
TABLE_A a
离开加入 TABLE_B b ON a.brand = b.brand
) b
开启 (a.id = b.id)
当匹配然后更新设置 a.yn_buy = b.yn_buy

有可能做这样的事情吗?也许使用立即执行,某种绑定...?

谢谢

【问题讨论】:

    标签: oracle build merge query-optimization


    【解决方案1】:

    如果我在您的特定情况下没有遗漏某些内容,则您不需要动态 SQL - 您可以简单地更改 TABLE_B 结构并使用静态 MERGE(因为我不知道您的标准有多复杂,这只是一个说明):

    SQL> create table table_a (id, brand, color, size#, model#, tn_buy) as
      2  select 1,    'A',          'blue',             'M',           'A', cast(null as varchar2(3)) from dual union all
      3  select 2,    'A',         'grey',              'X',          'C', cast(null as varchar2(3)) from dual union all
      4  select 3,    'B',         'red',               'X',           'B', cast(null as varchar2(3)) from dual union all
      5  select 4,    'C',        'blue',              'S',           'C', cast(null as varchar2(3)) from dual
      6  /
    
    Table screated.
    
    SQL> create table TABLE_B (brand, color, size#)
      2  as
      3  select 'A',          'grey', 'X' from dual union all
      4  select 'B',           'red', null from dual union all
      5  select 'C',          null, 'M' from dual
      6  /
    
    Table created.
    
    SQL> merge into TABLE_A a USING (
      2     select a.id, a.brand, CASE
      3     WHEN a.color = nvl(a.color, a.color) and a.size# = nvl(b.size#,a.size#)
      4     THEN 'Y' ELSE 'N' END yn_buy FROM
      5       TABLE_A a
      6       left join TABLE_B b ON a.brand = b.brand
      7  ) b
      8  ON (a.id = b.id)
      9  WHEN MATCHED THEN UPDATE set a.yn_buy = b.yn_buy
     10  /
    
    4 rows merged.
    
    SQL> select * from table_a order by id;
    
            ID B COLO S M YN_                                                       
    ---------- - ---- - - ---                                                       
             1 A blue M A N                                                         
             2 A grey X C Y                                                         
             3 B red  X B Y                                                         
             4 C blue S C N             
    

    但是你的条件很难用简单的静态条件来实现,那么你可以使用动态 SQL:

    SQL> create table TABLE_B1 (brand, criteria)
      2  as
      3  select 'A',          q'[color='grey' and size# in ('X','M')]' from dual union all
      4  select 'B',           q'[color = 'red']' from dual union all
      5  select 'C',          q'[size#='M']' from dual
      6  /
    
    Table created.
    
    SQL> update table_a set yn_buy = null;
    
    4 rows updated.
    
    SQL> commit;
    
    Committed.
    
    SQL> begin
      2    for cur in (select brand, criteria from table_b1) loop
      3      execute immediate
      4      'update table_a set yn_buy = case when '||cur.criteria||
      5      q'[ then 'Y' else 'N' end where brand = :1]' using cur.brand;
      6    end loop;
      7  end;
      8  /
    
    PL/SQL procedure completed.
    
    SQL> select * from table_a;
    
            ID B COLO S M YN_                                                       
    ---------- - ---- - - ---                                                       
             1 A blue M A N                                                         
             2 A grey X C Y                                                         
             3 B red  X B Y                                                         
             4 C blue S C N           
    

    【讨论】:

    • 谢谢!由于条款的复杂性,我将尝试使用第二个建议
    猜你喜欢
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 2020-08-21
    • 2012-11-23
    • 2018-04-18
    • 1970-01-01
    • 2019-04-08
    • 2012-12-21
    相关资源
    最近更新 更多