Возможно ли иметь предложение WHERE после предложения HAVING?

Можно ли использовать предложение WHERE после предложения HAVING?

Первое, что приходит мне в голову, это подзапросы, но я не уверен.

P.S. Если ответ утвердительный, не могли бы вы привести несколько примеров?


person cc.    schedule 04.11.2009    source источник
comment
Это вопрос с подвохом/интервью, или у вас есть реальная проблема, которую нужно решить?   -  person itsadok    schedule 04.11.2009
comment
да. Вопрос из интервью.   -  person cc.    schedule 04.11.2009


Ответы (5)


Нет, не в том же запросе.

Предложение where предшествует having и group by. Если вы хотите отфильтровать записи перед группировкой, условие будет в предложении where, а если вы хотите отфильтровать сгруппированные записи, условие будет в предложении having:

select ...
from ...
where ...
group by ...
having ...

Если ни один из них нельзя использовать по какой-либо странной причине, вы должны сделать запрос подзапросом, чтобы вы могли поместить предложение where во внешний запрос:

select ...
from (
   select ...
   from ...
   where ...
   group by ...
   having ...
) x
where ...
person Guffa    schedule 04.11.2009

Предложение HAVING — это просто предложение WHERE после GROUP BY. Почему бы не поместить условия WHERE в предложение HAVING?

person Nestor    schedule 04.11.2009
comment
Концептуально предложение HAVING применяется после операции GROUP BY, тогда как предложение WHERE применяется до него, поэтому теоретически возможна оптимизация путем «фильтрации» в предложении WHERE. На практике вам (как всегда) придется смотреть, как оптимизатор обрабатывает это, например. изучить план выполнения. Также обратите внимание на читателя-человека, который обычно ожидает увидеть «фильтрацию» в предложении WHERE (а не в предложениях соединения, предложениях HAVING и т. д.). - person onedaywhen; 04.11.2009

Если это вопрос с подвохом, это возможно, если WHERE и HAVING не находятся на том же уровне, как вы упомянули, с подзапросом.

Я думаю, что-то вроде этого будет работать

ИМЕЕТ значение = (ВЫБЕРИТЕ максимальное (значение) ИЗ foo, ГДЕ крит = 123)

p.s.: зачем ты спрашивал? У вас есть конкретная проблема?

p.s.s: Хорошо, глупый я, я пропустил тег "интервью*"...

person pascal    schedule 04.11.2009

Из справки SELECT

Порядок обработки предложений WHERE, GROUP BY и HAVING Следующие шаги показывают порядок обработки оператора SELECT с предложением WHERE, предложением GROUP BY и предложением HAVING.

Предложение FROM возвращает исходный набор результатов.

Предложение WHERE исключает строки, не соответствующие условию поиска.

Предложение GROUP BY собирает выбранные строки в одну группу для каждого уникального значения в предложении GROUP BY.

Агрегатные функции, указанные в списке выбора, вычисляют итоговые значения для каждой группы.

Предложение HAVING дополнительно исключает строки, не соответствующие условию поиска.

Так что нет, нельзя.

person Adriaan Stander    schedule 04.11.2009

В той же области ответ - нет. Если подзапросы разрешены, вы можете полностью избежать использования HAVING.

Я думаю, что HAVING это анахронизм. Хью Дарвен называет HAVING «Безумием структурированных запросов»:

В старом SQL предложение WHERE нельзя было использовать для результатов агрегирования, поэтому им пришлось изобрести HAVING (с тем же значением, что и WHERE):

SELECT D#, AVG(Salary) AS Avg_Sal
  FROM Emp
 GROUP 
    BY D#
HAVING AVG(Salary) > 999;

Но было бы у нас когда-нибудь HAVING, если бы в 1979 году можно было написать:

SELECT * 
  FROM (
        SELECT D#, AVG(Sal) AS Avg_Sal
          FROM Emp
         GROUP 
            BY D# 
       )
      AS dummy
WHERE Avg_Sal > 999;

Я сильно подозреваю, что ответ на вопрос Дарвен отрицательный.

person onedaywhen    schedule 04.11.2009