从表名称在当前查询中的表中查询

时间:2019-01-30 07:39:53

标签: sql oracle

我有这个查询: select main_value, subtable, subtable_column from table1

我想知道我可以在运行查询的同时从subtable查询值吗?

编辑 ----

table1结构

main_value varchar
subtable varchar
subtable_column varchar

分支结构(查询中的子表)

id number
branch_name varchar

当我从table1查询时,如果子表的值为branches,subtable_column的值为branch_name,则从分支中查询branch_name。(因为子表列的值是从查询中检索到的分支,列名是vise反之亦然。

编辑表格和示例 -----------------------------

table1

+-----------------+--------------------+  
| Field           | Type               |  
+-----------------+--------------------+  
| ID              | number(20,0)       |  
| subtable        | varchar2(50 BYTE)  |  
| subtable_column | varchar2(100 BYTE) |  
+-----------------+--------------------+  

分支机构

+-------------+-------------------+  
| Field       | Type              |  
+-------------+-------------------+  
| ID          | number(20,0)      |  
| branch_name | varchar2(50 BYTE) |  
+-------------+-------------------+  

注意:这些仅是示例,因此,请不要提出其他方法,而不要从当前查询中同时具有表名和列名的表中进行选择。

我在表1中有如下记录:

ID | subtable | subtable_column
-------------------------------
1  | branches | branch_nmae
2  | null     | null

和分支表如下:

ID | branch_name |
------------------
1  | new york
2  | colombo

输出:

+-------------+-------------------+---------------------------------+
| subtable    | subtable_column   | selected values from branches   |
+-------------+-------------------+---------------------------------+
| branches    | branch_name       | new york, colombo               |
| null        | null              |                                 |
+-------------+-------------------+---------------------------------+

2 个答案:

答案 0 :(得分:1)

如果您知道table1可能包含的所有可能的表和所有可能的列,则可以使用包含所有可能性的case when构建查询。像这样:

select id, subtable, subtable_column, 
       case 
       when subtable = 'branches' and subtable_column = 'branch_name' then 
         (select listagg(branch_name, ', ') within group (order by branch_name) 
            from branches) 
       when subtable = 'branches' and subtable_column = 'id' then 
         (select listagg(id, ', ') within group (order by id) 
            from branches) 
       end as subtable_values
  from table1;

但是,针对此类问题的更常见解决方案是使用动态SQL。因此,编写类似以下的函数:

create or replace function get_subtable_values(i_table in varchar2, i_column in varchar2)
  return varchar2 is

  v_sql varchar2(32767);
  v_ret varchar2(32767);
begin
  if i_table is null then
    return null;
  end if;

  v_sql := 'select listagg('||i_column||', '', '') within group (order by null) from '||i_table;
  execute immediate v_sql into v_ret;
  return v_ret;
end;

...并在查询中使用它:

select id, subtable, subtable_column, 
       get_subtable_values(subtable, subtable_column) as subtable_values
  from table1;

我的两个查询的测试数据和输出:

create table table1(id, subtable, subtable_column) as (
    select 1, 'branches', 'branch_name' from dual union all
    select 2, 'branches', 'id'          from dual union all
    select 3, null,       null          from dual); 

create table branches(id, branch_name) as (
    select 1, 'New York' from dual union all
    select 2, 'Colombo'  from dual );

结果:

    ID  SUBTABLE  SUBTABLE_COLUMN  SUBTABLE_VALUES
------  --------  ---------------  --------------------
     1  branches  branch_name      Colombo, New York
     2  branches  id               1, 2
     3  null      null             null

我使用了函数listagg(),该函数将所有值粘贴到一个字符串中,以逗号分隔。还可以返回varchars或用户定义类型的表。当然,可能存在许多问题,例如字符串太长,除varchar以外的数据类型,应处理异常等。但是您看到了可能。

答案 1 :(得分:0)

DirectoryIndex disabled
Options -MultiViews

此sql可以,但是效率较低