почему "ЛЮБОЙ" не работает должным образом? - PullRequest
3 голосов
/ 03 ноября 2011

Я изучаю SQL, используя Oracle 10g. Мне нужен запрос, который возвращает отдел с наибольшим количеством сотрудников, чтобы использовать его в обновленном предложении. Я уже решил это, но я не мог понять, почему этот запрос не будет работать:

select deptno
from (select deptno, 
             count(*) num 
        from emp 
       group by deptno)
where not num < any(select count(deptno) 
                      from emp 
                     group by deptno)

Это озадачивает меня больше, так как согласно документации это должно быть эквивалентно и оптимизировано для следующего:

select deptno 
  from (select deptno, 
               count(*) num 
          from emp 
         group by deptno )
 where not exists( select deptno, 
                          count(*) 
                     from emp 
                   having count(*) > num 
                    group by deptno)

Это работает без ошибок. Следующие также работают:

select deptno 
  from (select deptno, 
               count(*) num 
          from emp 
         group by deptno)
 where num = (select max(alias) 
                from (select count(deptno) alias 
                        from emp 
                       group by deptno))


select deptno 
  from emp
 group by deptno
 having not count(deptno) < any( select count(deptno) 
                                   from emp 
                                  group by deptno)

Edit. Вероятно, это поможет, если я отправлю возвращаемые значения внутренних выборок.

Первый выбор возвращает:

Dept. Number         Employees
30                   6
20                   5
10                   3

Последний возвращается (3,5,6)

Я проверил их индивидуально. Также странно, что если я введу значения вручную, они будут работать как положено и вернут 30 как департамент с большинством сотрудников.

select deptno
from (select deptno, 
             count(*) num 
        from emp 
       group by deptno)
where not num < any(6,5,3)

Я использую Oracle 10g 10.2.0.1.0

Последнее редактирование, вероятно. Все еще не знаю, что происходит, но поведение такое, как будто последний выбор возвращает ноль как-то. Поэтому, даже если я уберу «нет», он все равно ничего не выберет.

Если кому-то интересно, я тоже нашел это полезным: TSQL - НЕКОТОРЫЕ | ЛЮБЫЕ почему они одинаковые с разными именами? Прочитайте первый ответ. Вероятно, лучше избегать использования каких-либо / некоторых, всего.

Ответы [ 2 ]

2 голосов
/ 04 ноября 2011

Вот аналогичный пример, который может прояснить ситуацию (стандартный SQL, может быть легко преобразован для Oracle):

WITH T
     AS 
     (
      SELECT * 
        FROM (
              VALUES (0),
                     (1), 
                     (2),
                     (NULL)
             ) AS T (c)
     )
SELECT DISTINCT c
  FROM T
 WHERE 1 > ALL (SELECT c FROM T T2);

Возвращает пустое множество, что является разумным: учитывая наличие нулевого значения в таблице, 1 > NULL равно НЕИЗВЕСТНО, поэтому неизвестно, больше ли значение 1, чем все значения в наборе.

Однако добавление оператора NOT:

 WHERE NOT 1 > ALL (SELECT c FROM T T2);

возвращает все значения в наборе, включая нулевое значение. На первый взгляд это кажется неправильным: учитывая, что 1 > 2 - ЛОЖЬ, мы можем с уверенностью сказать, что значение 1 не больше, чем все значения в наборе, независимо от нуля.

Однако в этом случае NOT просто переворачивает предыдущий результат, т. Е. Противоположность всех строк - это не все строки! ;)

Далее рассмотрим отрицательное сравнение, используя столбец (а не буквальное значение 1):

WHERE NOT c > ALL (SELECT c FROM T T2);

На этот раз он возвращает все строки, кроме нулевого значения.

1 голос
/ 03 ноября 2011

Исправление (обновление)

not num < any(select ...)

должно совпадать с вашими другими запросами.Вы также можете попробовать этот вариант:

num >= ALL(select ...)

, но я не могу понять, почему ваш дает неправильные результаты.Возможно из-за приоритета not.Можете ли вы попробовать это вместо этого:

not ( num < ANY(select ...) )

Полные запросы:

select deptno
from (select deptno, count(*) num from emp group by deptno)
where num >= all(select count(deptno) from emp group by deptno)

и:

select deptno
from (select deptno, count(*) num from emp group by deptno)
where not ( num < any(select count(deptno) from emp group by deptno) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...