2014-08-29 55 views
0

我试图选择所有具有OWNERID或L1ID或L1列的表,但没有任何以下列,HID,DHID,SPHID,SPHID,LINKHID,NODEID和SITEID。用于从表中选择特定列的SQL查询优化

以下是我的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) 

请不要将其标记为重复。我已经尝试过其他的解决方案,他们似乎没有锻炼对我来说

回答

1

尽量不要存在/代替存在。只要您不需要从辅助表中选择值,这比IN快得多,特别是不会。基本原因是一旦匹配,评估就完成了。

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 
) 

但是,我不完全确定你的COUNT(*)= 1是什么意思。 OWNERID或L1ID或L1中只有一个,但在同一个表中没有说L1ID和L1?

如果您只关心是否存在您的一个或多个条件栏,即我如何以英文了解您的问题,那么我的代码将会起作用。如果您只需要其中一个存在,则需要不同的查询。

+0

是,只有OWNERID或L1ID或L1中的一个将在表中。它们都是一样的,但在不同的表中有不同的名称。同样适用于HID,DHID,... SITEID – schuma 2014-08-29 21:05:29

+0

我得到这个错误ORA-00904:“USER_TAB_COLUMNS”。“TABLE_NAME”:无效标识符 00904. 00000 - “%s:无效标识符” – schuma 2014-08-29 21:11:55

+0

例如:如果table1有L1和OWNERID,table2只有L1。我拒绝table1并接受table2 – schuma 2014-08-29 21:13:51

0

尝试做这样做:

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; 
+0

感谢您的解决方案。但它没有奏效。它给了我仍然有HID或其他列的表格,我不想要 – schuma 2014-08-29 21:01:07

+0

@ user3571754。 。 。这不应该为您提供HID作为列的表,除非列的大小写是问题。您可能希望在整个查询中输入“upper(column_name)”。 – 2014-08-29 22:24:31

0
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