Почему добавление count (*) к оператору select заставляет строку существовать в подзапросе? - PullRequest
2 голосов
/ 10 июня 2009

В Oracle 9i, почему следующее производит результат 'abc'

select 'abc ' || (select txt from 
     (select 'xyz' as txt from dual where 1=2)) 
from dual

пока выдает 'abc xyz':

select 'abc ' || (select txt from 
     (select count(*), 'xyz' as txt from dual where 1=2)) 
from dual

Почему добавление count (*) к подзапросу приводит к другому поведению? Должен ли предикат where 1=2 исключать какие-либо результаты в подзапросе?

Ответы [ 5 ]

15 голосов
/ 10 июня 2009
select count(*) from dual where 1=2

возвращает 0. То есть строка со значением ноль.

4 голосов
/ 10 июня 2009

Возвращает счетчик всего в подзапросе, который равен 0. Использование агрегатных функций всегда (и правильно) ведет себя так и является частью стандарта SQL.

0 голосов
/ 11 июня 2009
 (select 'xyz' as txt from dual where 1=2)) 

Этот подзапрос НЕ ВОЗВРАЩАЕТСЯ НИКАКИМИ СТРОКАМИ.

 (select count(*), 'xyz' as txt from dual where 1=2)) 

Этот подзапрос возвращает 1 строку ВСЕ ВРЕМЯ.

В этом причина разного поведения.

0 голосов
/ 10 июня 2009

Понимание работы агрегатных функций в SQL имеет решающее значение для написания правильных запросов. При добавлении агрегатной функции (например, суммы, среднего, минимального, максимального, счетного) к запросу вы запрашиваете у базы данных выполнение групповой операции с набором результатов. Большинство агрегатов, таких как min и max, будут возвращать ноль, когда представлены с пустым набором строк для работы. Исключением является count () - он (правильно) возвращает 0, когда представлен с пустым набором или строками.

Этот вопрос возник из анализа гораздо более сложного запроса - с несколькими выражениями подзапроса в предложении select. Как оказалось, добавление count (*) в выражение select вызвало некоторый хаос в результатах - так как оно начало возвращать значение, где ничего не ожидалось.

То, что действительно хотел разработчик, - это случай, когда count(*) будет давать ноль. Самый простой способ добиться этого - использовать аналитику в Oracle. Запрос может быть написан для использования эквивалента аналитического счета: count(*) over ()

select 'abc ' || (select txt from 
     (select count(*) over (), 'xyz' as txt from dual where 1=2)) 
from dual
0 голосов
/ 10 июня 2009

count всегда будет возвращать числовое значение, 0 или положительное целое число, поэтому у вас всегда будет одна строка в наборе результатов.

Обратите внимание, что другие агрегатные функции могут возвращать NULL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...