我有2个表TAB_A
和TAB_B
,TAB_A
包含TAB_B
的列名(它不包含所有列)。我需要构建SQL查询(而不是PL / SQL)来列出每个列的值,如下所示
TAB_A.FIELD
COLUMN_1
COLUMN_2
COLUMN_3
TAB_B
COLUMN_1 COLUMN_2 COLUMN_3 COLUMN_4
1 A S 100
2 V F 200
3 B 300
Output
FIELD VALUE
COLUMN_1 1
COLUMN_1 2
COLUMN_1 3
COLUMN_2 A
COLUMN_2 V
COLUMN_3 S
COLUMN_3 F
COLUMN_3 B
我尝试了几件事,都是以文本而不是列名取值。
答案 0 :(得分:0)
这样做你想要的吗?
select 'column1' as field, column1 as value from t where column1 is not null
union all
select 'column2' as field, column2 as value from t where column2 is not null
union all
select 'column3' as field, column3 as value from t where column3 is not null
union all
select 'column4' as field, column4 as value from t where column3 is not null;
这是一个“unpivot”操作,union all
是一个合理的方法,当没有太多列且数据不是太大时。如果需要根据另一个表选择列,则需要使用动态SQL。
答案 1 :(得分:0)
如果要在外部构建查询以进行解析和执行,则可以。作为预解析的SQL语句,您无法动态地将对象名称与检索到的值进行比较,因为解析器必须执行查询以查明它是否有效。或者如何处理tab_a.field中的列名在tab_b中作为实际列不存在?
那就是说,如果你能分两步完成,你可以:
1)从tab_a.field中选择不同值的列表,并将它们组装成以逗号分隔的列表作为字符串文字。
2)将字符串文字放入正确的位置: 从tab_b中选择col_name,val unpivot((:your_list_from_step_1)中col_name的val) 按col_name,val
排序3)执行它。
但即便如此,只有tab_b中的所有列都具有相同的基本数据类型时,这才有效。您如何期望Oracle在单个列中检索数字,字符串和日期的混合?返回游标是键入的。
要解决这个问题,您需要查询数据字典以查找tab_b中所有可能列的所有数据类型,并执行类似于在顶部写入视图以将它们全部规范化为单个数据类型的操作(可能varchar2)可以在单个游标列中返回。
如果你真的想走这条路 - 我不会羡慕你的头痛。但我确实保证了一件事 - 您无法找到将指向对象名称的查询元数据合并到预先准备好的预解析查询中的方法。 Oracle的解析器仅在查询中将对象名称与字符串文字匹配 - 而不是动态检索的值。