разница между where и have в отношении псевдонимов

Если я создаю псевдоним в предложении select, то я не могу использовать его в предложении where, потому что в соответствии с порядком выполнения sql-запросов where предшествует select.

Но я могу создать псевдоним в предложении select и использовать его в предложении having, хотя having предшествует select.

Почему это так?

Ex:

select type, (case when number>25 then 1 else 0 end) inc 
from animals
where inc='1';

это не сработает. Но,

select type, (case when number>25 then 1 else 0 end) inc 
from animals
having inc='1'; 

Это работает. Почему так?


person pooja    schedule 23.08.2012    source источник
comment
Это расширение стандарта MySQL. Например, вы не можете ссылаться на псевдонимы столбцов в having в SQL Server.   -  person Martin Smith    schedule 23.08.2012


Ответы (1)


В основном потому, что они были определены для разных целей. Предложение WHERE предназначено для фильтрации записей, а предложение HAVING предназначено для фильтрации с помощью агрегатных функций (GROUP BY). Во втором запросе используется неявная фильтрация GROUP BY, поэтому, например, если вы добавите еще один столбец в предложение SELECT, вы получите другие результаты.

ИЗМЕНИТЬ на основе исправления Мартина Смита

HAVING был создан, чтобы разрешить фильтрацию строк, полученных в результате GROUP BY. Если GROUP BY не указано, весь результат считается группой.

Если ни <where clause>, ни <group by clause> не указаны, то пусть T будет результатом предыдущего <from clause>

or

... группа - это вся таблица, если не указано <group by clause>

EDIT 2 Теперь о Псевдониме:

Спецификация предложения WHERE относительно ссылок на столбцы в условии поиска говорит следующее:

Каждое <column reference>, непосредственно содержащееся в <search condition>, должно однозначно ссылаться на столбец T или быть внешней ссылкой.

См.: 7.6 <where clause>, Синтаксическое правило 1.

Спецификация предложения HAVING относительно ссылок на столбцы в условии поиска говорит следующее:

Каждое <column reference>, непосредственно содержащееся в <search condition>, должно однозначно ссылаться на столбец группировки T или быть внешней ссылкой.

См.: 7.8 <having clause>, Синтаксическое правило 1.

А столбец группировки определяется как:

Столбец, указанный в <group by clause>, является столбцом группировки.

Итак, в заключение WHERE должен ссылаться на столбец таблицы, а предложение HAVING должно ссылаться на группирующий столбец группы строк.

(второй проект неофициальной проверки) ISO/IEC 9075:1992, язык баз данных SQL - 30 июля 1992 г.

person davidmontoyago    schedule 23.08.2012
comment
Но как получилось, что «иметь» подбирает псевдоним еще до того, как будет выполнен «выбор»? - person pooja; 23.08.2012
comment
Любая цитата о том, что в стандартном SQL вы не можете использовать предложение HAVING без GROUP BY? - person Martin Smith; 23.08.2012
comment
Без цитирования, но хорошо известно, что HAVING был создан для фильтрации строк, полученных в результате предложения GROUP BY. en.wikipedia.org/wiki/SQL - person davidmontoyago; 23.08.2012
comment
@user1619966 user1619966 HAVING не получает псевдоним до выполнения выбора. Каждый раз, когда вы запускаете SQL-запрос в большинстве баз данных, механизм БД обрабатывает ваш SQL и создает план выполнения, SQL трансформируется и улучшается, и то, что вы видите на экране, не всегда точно соответствует тому, что выполняется. - person davidmontoyago; 23.08.2012
comment
SELECT SUM(number) FROM SomeTable - это вполне допустимый SQL. Почти уверен, что SELECT SUM(number) FROM SomeTable HAVING SUM(number) > 1000 тоже, и ваша последняя строка неверна. Не стесняйтесь указывать мне на соответствующую часть спецификации Там, где вы считаете, это запрещено. Все, что я вижу, это <table expression> ::= <from clause> [ <where clause> ][ <group by clause> ][ <having clause> ], указывающее, что любая перестановка из трех в порядке. - person Martin Smith; 23.08.2012
comment
Извините, но я все еще не ясно. Позвольте мне сказать это так. Если мы создадим псевдоним в операторе «выбрать», мы не сможем использовать его в предложении «где». Если мы хотим его использовать, то это должно быть что-то вроде этого: выберите t1.type, t1.inc из (выберите тип, (случай, когда число>25, затем 1, иначе 0 заканчивается)inc от животных) t1, где t1.inc=1 ; Но с «обладанием» мы можем его использовать. почему так? (Мой вопрос больше касается использования псевдонимов) - person pooja; 23.08.2012
comment
@ user1619966 ответ был улучшен. - person davidmontoyago; 23.08.2012
comment
@davidmontoyago спасибо, последний пост (РЕДАКТИРОВАТЬ 2 относительно Псевдонима) был действительно полезен! - person pooja; 23.08.2012
comment
@davidmontoyago Не могли бы вы дать еще одно пояснение ... В примере, упомянутом в самом начале, поскольку «группировать по» не используется с «иметь», он рассматривает всю таблицу как группу и, таким образом, может понять псевдоним?.. Это правильный ход мысли? - person pooja; 23.08.2012