将关联子查询的查询简化为简单连接

时间:2011-02-14 07:14:25

标签: sql oracle

我需要帮助来简化以下查询。

我可以在下面的查询中使用Group By / having Count子句但是使用相关子查询来检查'0'计数。

现在,我被要求将以下查询简化为简单连接!。

我尝试将查询合并为一个。但输出不同。

你能否提出一些简化查询的建议,即检查'0'计数。

select distinct tab1.col1
  from tab1
  where tab1.col2 = 'A'
  And 0 = (select count(tab2.col1)
            from tab2
            where tab2.col2 = 'B'
            and tab2.col1 = tab1.col1)

2 个答案:

答案 0 :(得分:3)

这类事情通常会写成NOT EXISTS

SELECT distinct tab1.col1
  FROM tab1
 WHERE tab1.col2 = 'A'
   AND NOT EXISTS( 
      SELECT 1
        FROM tab2
       WHERE tab2.col2 = 'B'
         AND tab2.col1 = tab1.col1 )

但是你也可以写

SELECT tab1.col1, count(tab2.col1)
  FROM (SELECT * FROM tab1 WHERE col2 = 'A') tab1,
       (SELECT * FROM tab2 WHERE col2 = 'B') tab2 
 WHERE tab1.col1 = tab2.col2(+)
 GROUP BY tab1.col1
HAVING count(tab2.col1) = 0

答案 1 :(得分:3)

尝试其中一些。 如果col1声明为非null,则前两个查询具有相同的执行计划(反连接)。第二种选择是我的个人建议,因为它最符合您的要求。

-- Non-correlated subquery
select distinct col1
  from tab1
 where col2 = 'A'
   and col1 not in(select col1 
                     from tab2 
                    where col2 = 'B');

-- Correlated subquery
select distinct col1
  from tab1
 where col2 = 'A'
   and not exists(select 'x'
                    from tab2 
                   where tab2.col2 = 'B'
                     and tab2.col1 = tab1.col1);

-- Using join
select distinct tab1.col1
  from tab1 
  left join tab2 on(tab2.col2 = 'B' and tab2.col1 = tab1.col1)
 where tab1.col2 = 'A'
   and tab2.col1 is null;

-- Using aggregation   
select tab1.col1
  from tab1 
  left join tab2 on(tab2.col2 = 'B' and tab2.col1 = tab1.col1)
 where tab1.col2 = 'A'
 group 
    by tab1.col1
having count(tab2.col2) = 0;