假设我有一些名为* _FOO:
的列的表create table a(x number, x_foo number);
create table b(z_foo number);
如何查询USER_TAB_COLS以获取(a)包含X和X_FOO的列的列表,
select table_name, short_col, foo_col from ... user_tab_cols ...
TABLE_NAME SHORT_COL FOO_COL
---------- --------- -------
A X X_FOO
和(b)没有相应X的X_FOO列表?
TABLE_NAME FOO_COL
---------- -------
B Z_FOO
这个问题是特定于Oracle的,因为查询会使用USER_TAB_COLS,但我认为查询连接将是通用SQL吗?
答案 0 :(得分:2)
对于第一个基于连接的简单连接将执行:
select utc1.table_name, utc1.column_name, utc2.column_name
from user_tab_columns utc1
join user_tab_columns utc2
on utc2.table_name = utc1.table_name
and utc2.column_name = utc1.column_name || '_FOO';
TABLE_NAME COLUMN_NAME COLUMN_NAME
------------------------------ ------------------------------ ------------------------------
A X X_FOO
对于第二个,您可以从名为'%_FOO'
的任何内容开始,并检查名称较短的列是否不存在:
select utc1.table_name, utc1.column_name
from user_tab_columns utc1
where utc1.column_name like '%\_FOO' escape '\'
and not exists (
select null
from user_tab_columns utc2
where utc2.table_name = utc1.table_name
and utc2.column_name = substr(utc1.column_name, 1, length(utc1.column_name) -4)
);
TABLE_NAME COLUMN_NAME
------------------------------ ------------------------------
B Z_FOO
如果您愿意,也可以使用外部联接:
select utc2.table_name, utc2.column_name
from user_tab_columns utc1
right outer join user_tab_columns utc2
on utc2.table_name = utc1.table_name
and utc2.column_name = utc1.column_name || '_FOO'
where utc2.column_name like '%\_FOO' escape '\'
and utc1.column_name is null;
TABLE_NAME COLUMN_NAME
------------------------------ ------------------------------
B Z_FOO
SQL Fiddle有两个外连接示例。
答案 1 :(得分:0)
你是否经历过这样的事情?
with sample_data as (select 'A' table_name, 'COL1' column_name from dual union all
select 'A' table_name, 'COL2' column_name from dual union all
select 'A' table_name, 'COL3' column_name from dual union all
select 'B' table_name, 'COL1' column_name from dual union all
select 'B' table_name, 'COL2' column_name from dual union all
select 'C' table_name, 'COL2' column_name from dual union all
select 'C' table_name, 'COL3' column_name from dual union all
select 'C' table_name, 'COL4' column_name from dual union all
select 'D' table_name, 'COL1' column_name from dual)
select distinct table_name,
case when count(*) over (partition by table_name) = 2 then 'Both cols present'
when count(*) over (partition by table_name) = 1 and column_name = 'COL1' then 'COL1 present only'
when count(*) over (partition by table_name) = 1 and column_name = 'COL2' then 'COL2 present only'
end cols_present
from sample_data
where column_name in ('COL1', 'COL2');
TABLE_NAME COLS_PRESENT
---------- -----------------
A Both cols present
B Both cols present
C COL2 present only
D COL1 present only
也许是这样的:
with sample_data as (select 'A' table_name, 'COL1' column_name from dual union all
select 'A' table_name, 'COL2' column_name from dual union all
select 'A' table_name, 'COL3' column_name from dual union all
select 'B' table_name, 'COL1' column_name from dual union all
select 'B' table_name, 'COL2' column_name from dual union all
select 'C' table_name, 'COL2' column_name from dual union all
select 'C' table_name, 'COL3' column_name from dual union all
select 'C' table_name, 'COL4' column_name from dual union all
select 'D' table_name, 'COL1' column_name from dual)
select table_name,
max(case when column_name = 'COL1' then column_name end) first_col,
max(case when column_name = 'COL2' then column_name end) first_col
from sample_data
where column_name in ('COL1', 'COL2')
group by table_name;
TABLE_NAME FIRST_COL FIRST_COL_1
---------- --------- -----------
A COL1 COL2
B COL1 COL2
C COL2
D COL1
(显然,我刚刚模拟了一个名为sample_data的子查询,其中包含一些数据;您只需直接查询user_tab_columns表。)