Упрощение запроса с коррелированным подзапросом до простых объединений - PullRequest
0 голосов
/ 14 февраля 2011

Мне нужна помощь в упрощении запроса ниже.

Я смог проверить счетчик '0', не используя предложения Group By / с количеством Count в приведенном ниже запросе, но с коррелированным подзапросом.

Теперь меня попросили упростить приведенный ниже запрос как простые объединения!

Я попытался объединить запрос в один. Но выход отличается.

Не могли бы вы предложить любую другую идею по упрощению запроса, которая проверяет счетчик '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 ]

3 голосов
/ 14 февраля 2011

Попробуйте некоторые из них.Если col1 объявлен как не нулевой, первые два запроса имеют одинаковый план выполнения (анти-объединения).Второй вариант - мой личный совет, так как он наилучшим образом соответствует вашим требованиям.

-- 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;
3 голосов
/ 14 февраля 2011

Такие вещи обычно записываются как НЕ СУЩЕСТВУЮЩИЕ

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...