简体   繁体   English

在Oracle sql中,plsql创建了一个构建变量的sql

[英]Oracle sql,plsql create a sql building up the variables

Wonder if someone could guide me in the right direction. 不知道有人能引导我朝着正确的方向前进。

I have a data table structure as below: 我有一个数据表结构如下:

table2_type char (1)

table2_key char (40)

table2_reftype char (20)

table2_seq char (10)

table2_ref char (50)

and data rows like(comma separated for readability only): 和数据行(为逗号分隔,仅为了可读性):

I,123456789,typea,0000000001,abc

I,123456789,typeb,0000000002,999

I,123456789,typec,0000000003,9z9

I,123456789,typed,0000000004,zyx

I,123456789,typee,0000000005,qwe

I,987654321,typea,0000000006,bcd

I,987654321,typeb,0000000007,444

What I have to do at the moment to get all the table_ref values for the same table_key values is below (spaced for ease of reading): 为了获得相同table_key值的所有table_ref值,我现在必须做的是(为便于阅读而间隔):

select table1_bkey,

nvl((case when (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typea',20)) is not null then (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typea',20)) else (select table2_ref from table2 where table2_key = table1_alt and table2_reftype = rpad('typea',20)) end),' ') as REF_A,

nvl((case when (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typeb',20)) is not null then (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typeb',20)) else (select table2_ref from table2 where table2_key = table1_alt and table2_reftype = rpad('typeb',20)) end),' ') as REF_B,

nvl((case when (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typec',20)) is not null then (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typec',20)) else (select table2_ref from table2 where table2_key = table1_alt and table2_reftype = rpad('typec',20)) end),' ') as REF_C,

nvl((case when (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typed',20)) is not null then (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typed',20)) else (select table2_ref from table2 where table2_key = table1_alt and table2_reftype = rpad('typed',20)) end),' ') as REF_D,

nvl((case when (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typee',20)) is not null then (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad('typee',20)) else (select table2_ref from table2 where table2_key = table1_alt and table2_reftype = rpad('typee',20)) end),' ') as REF_E

from table1 where table1_bkey = '123456789';

I currently could have up to 25 different table2_reftype per table2_key so I have to do 25 case statements. 我目前每个table2_key最多可以有25个不同的table2_reftype,所以我必须做25个case语句。 And if/when new table2_reftype are added I have to do new case statements. 如果/当添加新的table2_reftype时,我必须做新的case语句。

My question, is there a way to get all the table2_reftype values per table2_key without having to do multiple case statements eg: 我的问题是,有没有办法获得每个table2_key的所有table2_reftype值,而不必做多个case语句,例如:

illustration purpose only, not to be taking literal as code in any way!! 仅用于说明目的,不以任何方式将字面作为代码!!

while table2_key = table1_bkey

get table2_reftype 

then for each table2_reftype 

nvl((case when (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad(<table2_reftype variable>,20)) is not null then (select table2_ref from table2 where table2_key = table1_bkey and table2_reftype = rpad(<table2_reftype variable>,20)) else (select table2_ref from table2 where table2_key = table1_alt and table2_reftype = rpad(<table2_reftype variable>,20)) end),' ') as REF_<table2_reftype  variable>

where table1_bkey = '123456789';

First post so hope I have put enough information. 第一篇文章,希望我已经提供了足够的信息。

I think you could use something like this: 我想你可以使用这样的东西:

select key, ref_a, ref_b, ref_c
  from (
    select table1_bkey key, table2_ref ref, trim(table2_reftype) type, 
           row_number() over (partition by table1_bkey, table2_reftype 
                              order by case table2_key when table1_bkey then 1 else 2 end) rn
      from table1
      left join table2 
        on trim(table2_reftype) in ('typea', 'typeb', 'typec')
        and table2_key in (table1_bkey, table1_alt))
  pivot (max(ref) for type in ('typea' ref_a, 'typeb' ref_b, 'typec' ref_c))
  where rn = 1

dbfiddle demo dbfiddle演示

What is going on here? 这里发生了什么? I left join -ed both tables using your conditions. 我根据你的条件left join两张桌子。 Then I assigned rn which depends on if match is done on base key or alternate key. 然后我分配了rn ,这取决于是否在基本密钥或备用密钥上进行匹配。 Base has higher priority, so in case both were found second is removed ( where rn = 1 ). Base具有更高的优先级,因此如果发现二者都被删除( where rn = 1 )。 Rest was easy, just pivot data for types which you hardcoded. 休息很简单,只需对您硬编码的类型进行数据透视。 Also please note that I trimmed ref_type . 另请注意我修剪了ref_type

This is example for 3 types, when you add new, just put it in both lists. 这是3种类型的示例,当您添加新类型时,只需将其放入两个列表中。 As you can see in my dbfiddle query works, but I had to imagine some data which you did not describe (for table1 ). 正如您在我的dbfiddle查询中所看到的那样,但我不得不想象一些您没有描述的数据(对于table1 )。

In case something is wrong and you would not be able to correct / adapt this solution please edit your question and provide sample data for both tables in the form of working create and insert statements and show us desired result for this data. 如果出现问题并且您无法纠正/调整此解决方案,请编辑您的问题并以工作createinsert语句的形式提供两个表的样本数据,并向我们显示此数据的所需结果。

You can also solve it like you described in your pseudo-code, but this requires either dynamic PLSQL, either constructing query in some other code (I did similiar things in .NET). 您也可以像在伪代码中描述的那样解决它,但这需要动态PLSQL,要么在其他代码中构造查询(我在.NET中做过类似的事情)。 Why? 为什么? Because Oracle has to know all columns when it compiles query. 因为Oracle在编译查询时必须知道所有列。

I hope this helps :) 我希望这有帮助 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM