用于从表中选择特定列的SQL查询优化

用于从表中选择特定列的SQL查询优化,sql,oracle,optimization,Sql,Oracle,Optimization,我正在尝试选择所有具有OWNERID、L1ID或L1列,但没有以下任何列的表:HID、DHID、SPHID、SPHID、LINKHID、NODEID和SITEID 下面是我的SQL查询。这需要很长时间。你能给我一个更好的解决方案或优化这个查询吗 SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME NOT IN ( SELECT TABLE_NAME

我正在尝试选择所有具有OWNERID、L1ID或L1列,但没有以下任何列的表:HID、DHID、SPHID、SPHID、LINKHID、NODEID和SITEID

下面是我的SQL查询。这需要很长时间。你能给我一个更好的解决方案或优化这个查询吗

SELECT 
      TABLE_NAME 
   FROM 
      USER_TABLES
   WHERE 
         TABLE_NAME NOT IN (
            SELECT TABLE_NAME 
               FROM USER_TAB_COLUMNS 
               WHERE COLUMN_NAME IN('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID')
               GROUP BY TABLE_NAME 
               HAVING COUNT(*) = 1)
      AND TABLE_NAME IN (
            SELECT TABLE_NAME 
               FROM USER_TAB_COLUMNS 
               WHERE COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1')
               GROUP BY TABLE_NAME 
               HAVING COUNT(*) = 1)
请不要将此标记为重复。我已经尝试过其他解决方案,但它们似乎不适合我

试着这样做:

SELECT TABLE_NAME 
FROM USER_TAB_COLUMNS
 GROUP BY TABLE_NAME
HAVING SUM(CASE WHEN COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1') THEN 1 ELSE 0 END) = 1 AND
       SUM(CASE WHEN COLUMN_NAME IN ('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID') THEN 1 ELSE 0 END) = 0;

尝试不存在/改为存在。只要您不需要从辅助表中选择值,这就比中快得多,尤其是在中。最基本的原因是,只要有匹配项,就会进行评估

SELECT 
TABLE_NAME 
FROM USER_TABLES
WHERE NOT EXISTS
(select 1
  FROM USER_TAB_COLUMNS
  WHERE COLUMN_NAME IN('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID')
  AND USER_TABLES.TABLE_NAME = USER_TAB_COLUMNS.TABLE_NAME
)
and EXISTS (
  SELECT 1 
  FROM USER_TAB_COLUMNS 
  WHERE COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1')
  AND USER_TABLES.TABLE_NAME = USER_TAB_COLUMNS.TABLE_NAME
)
但是,我不能完全确定您的计数(*)=1的含义。只有OWNERID或L1ID或L1中的一个,但不说L1ID和L1在同一个表中


如果您只关心您的一个或多个条件列是否存在,即我如何理解您的英语问题,那么我编写的代码将起作用。如果您只需要其中一个,则需要进行不同的查询。

谢谢您的解决方案。但它没有起作用。它给了我仍然有隐藏的表或其他我没有的列want@user3571754 . . . 除非列的大小写是一个问题,否则这不应该为您提供隐藏为列的表。您可能希望在整个查询过程中输入
upper(column\u name)
。是的,表中只有OWNERID、L1ID或L1中的一个。它们都是相同的,但在不同的表中有不同的名称。这同样适用于HID、DHID等。SITEIDI收到此错误ORA-00904:“用户选项卡列”。“表名称”:无效标识符00904。00000-“%s:无效标识符”示例:如果表1具有L1和OWNERID,则表2仅具有L1。我拒绝表1,接受表2。我的查询耗时153秒,而你的查询只需4秒。非常感谢。不客气。使用子查询的IN/NOT IN子句(即,不是列名列表,这些列名按原样都可以)总是可以替换为适当的EXISTS/NOT EXISTS,这些列名与IN/NOT IN相对应。
With exclude AS (
  select TABLE_NAME
  FROM USER_TAB_COLUMNS
  WHERE COLUMN_NAME IN('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID')
  GROUP BY TABLE_NAME
)
, preInclude AS (
  SELECT TABLE_NAME
  FROM USER_TAB_COLUMNS 
  WHERE COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1')
  GROUP BY TABLE_NAME
 ) 
, Include AS (
  SELECT preInclude.TABLE_NAME
  FROM preInclude
  LEFT JOIN exclude ON preIncude.TABLE_NAME = exclude.TABLE_NAME
  WHERE exclude.TABLE_NAME is NULL
)

SELECT * 
FROM Include