SQL查询不在列表中的表

时间:2017-01-24 09:35:59

标签: sql oracle select

我执行此查询以获取所有表 -

SELECT table_name FROM user_tables

这返回了100个结果。我现在执行此查询以根据特定条件获取表列表

select distinct table_name
from all_tab_columns
where column_name = 'my_column_id'
order by table_name

这返回了66行。是否有查询我可以获取剩余的34个表?

6 个答案:

答案 0 :(得分:2)

一种方法是使用NOT EXISTS

select table_name 
from user_tables t
where not exists(
    select table_name 
    from all_tab_columns c
    where column_name='my_column_id' 
    and t.table_name = c.table_name
)
order by table_name;

答案 1 :(得分:2)

只需使用NOT EXISTS返回没有具有该名称的列的每个表:

SELECT table_name
FROM user_tables ut
WHERE NOT EXISTS (select table_name
                  from all_tab_columns atc
                  where atc.column_name = 'my_column_id'
                    and ut.table_name = atc.table_name)

您还可以使用EXCEPT组合两个原始查询:

SELECT table_name
FROM user_tables ut
EXCEPT
select table_name
from all_tab_columns
where column_name = 'my_column_id'

答案 2 :(得分:1)

从我认为您的要求使用UNION ALL然后执行相反的WHERE条款。

SELECT DISTINCT table_name 
FROM all_tab_columns 
WHERE column_name = 'my_column_id' 
ORDER BY table_name
UNION ALL
SELECT DISTINCT table_name 
FROM all_tab_columns 
WHERE column_name != 'my_column_id' 
ORDER BY table_name

或者,如果您只想要34,则可以使用NOT IN并使用第一个查询。

SELECT DISTINCT table_name 
FROM all_tab_columns 
WHERE table_name NOT IN (SELECT table_name 
                         FROM all_tab_columns 
                         WHERE column_name = 'my_column_id' )
ORDER BY table_name

答案 3 :(得分:1)

使用not in

select distinct table_name 
from all_tab_columns 
where table name not in
(
select table_name
from all_tab_columns 
where column_name = 'my_column_id'
)
order by table_name;

值得注意的是,not exists速度更快,但在数千小时的数据集中,not in会很好(并且更容易理解为概念)

答案 4 :(得分:1)

如果您希望数据全部在一个查询中:

SELECT t.table_name,
       CASE WHEN c.table_name IS NOT NULL THEN 1 ELSE 0 END
         AS has_column
FROM   user_tables t
       LEFT OUTER JOIN
       user_tab_columns c
       ON (    t.table_name  = c.table_name
           AND c.column_name = 'MY_COLUMN_NAME' );

(注意:默认情况下,Oracle会将表名和列名转换为大写[以便从区分大小写的问题中抽象用户],除非您用双引号将它们包围起来;因此,您可能需要列名称大写。如果可能的话,你应该避免在查询中使用双引号,因为它会造成混淆。)

如果您只想要不匹配的列:

SELECT table_name
FROM   user_tables
MINUS
SELECT table_name
FROM   user_tab_columns
WHERE  column_name = 'my_column_id';

或者

SELECT table_name
FROM   user_tables t
WHERE  NOT EXISTS ( 
         SELECT 1
         FROM   user_tab_columns c
         WHERE  column_name  = 'my_column_id'
         AND    t.table_name = c.table_name
       );

或者

SELECT table_name
FROM   user_tables
WHERE  table_name NOT IN ( 
         SELECT table_name
         FROM   user_tab_columns
         WHERE  column_name  = 'my_column_id'
       );

答案 5 :(得分:1)

在比较USER_TABLESUSER_TAB_COLUMNS时,您应该非常小心,如下所示

select count(*) cnt from user_tables;

       CNT
----------
         1 

select  count(distinct table_name) cnt
from all_tab_columns
where column_name = 'my_column_id';   

       CNT
----------
         3

您看到USER_TAB_COLUMNS中的表格多于USER_TABLES

怎么可能?视图USER_TAB_COLUMNS(与其名称相反)也包含 VIEW 列,因此{{>>算术(MINUS,NOT IN等)表名称之间的{{} 1}}和USER_TABLES并不总是有意义的。