SQL - использование псевдонима в Group By - PullRequest
128 голосов
/ 01 октября 2010

Просто любопытно, синтаксис SQL.Поэтому, если у меня есть

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY itemName, FirstLetter

Это было бы неправильно, потому что

GROUP BY itemName, FirstLetter 

действительно должно быть

GROUP BY itemName, substring(itemName, 1,1)

Но почему мы не можем просто использовать первое дляудобство?

Ответы [ 9 ]

247 голосов
/ 01 октября 2010

SQL реализован так, как если бы запрос выполнялся в следующем порядке:

  1. Предложение FROM
  2. Предложение WHERE
  3. Предложение GROUP BY
  4. Предложение HAVING
  5. Предложение SELECT
  6. Предложение ORDER BY

В большинстве систем реляционных баз данных этот порядок объясняет, какие имена (столбцы или псевдонимы) действительны, поскольку они должныбыли введены на предыдущем шаге.

Таким образом, в Oracle и SQL Server нельзя использовать термин в предложении GROUP BY, который вы определяете в предложении SELECT, поскольку GROUP BY выполняется перед предложением SELECT.

Хотя есть исключения: MySQL и Postgres, кажется, обладают дополнительным умом, который позволяет это.

25 голосов
/ 01 октября 2010

Вы всегда можете использовать подзапрос, чтобы вы могли использовать псевдоним; Конечно, проверьте производительность (возможно, сервер БД будет работать одинаково, но никогда не повредит):

SELECT ItemName, FirstLetter, COUNT(ItemName)
FROM (
    SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
    FROM table1
    ) ItemNames
GROUP BY ItemName, FirstLetter
15 голосов
/ 01 октября 2010

По крайней мере, в PostgreSQL вы можете использовать номер столбца в наборе результатов в предложении GROUP BY:

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY 1, 2

Конечно, это становится проблемой, если вы делаете это в интерактивном режиме и редактируете запросизменить количество или порядок столбцов в результате.Но до сих пор.

12 голосов
/ 01 октября 2010

SQL Server не позволяет ссылаться на псевдоним в предложении GROUP BY из-за логического порядка обработки.Предложение GROUP BY обрабатывается до предложения SELECT, поэтому псевдоним неизвестен при оценке предложения GROUP BY.Это также объясняет, почему вы можете использовать псевдоним в предложении ORDER BY.

Вот один источник информации о этапах логической обработки SQL Server .

4 голосов
/ 13 декабря 2016

Я не отвечаю, почему это так, но хотел только обойти это ограничение в SQL Server, используя CROSS APPLY для создания псевдонима.Затем вы используете его в предложении GROUP BY, например:

SELECT 
 itemName as ItemName,
 FirstLetter,
 Count(itemName)
FROM table1
CROSS APPLY (SELECT substring(itemName, 1,1) as FirstLetter) Alias
GROUP BY itemName, FirstLetter
4 голосов
/ 23 апреля 2016

Внимание, использование псевдонима в Group By (для служб, которые его поддерживают, например, postgres) может привести к непредвиденным результатам.Например, если вы создаете псевдоним, который уже существует во внутреннем операторе, Group By выберет имя внутреннего поля.

-- Working example in postgres
select col1 as col1_1, avg(col3) as col2_1
from
    (select gender as col1, maritalstatus as col2, 
    yearlyincome as col3 from customer) as layer_1
group by col1_1;

-- Failing example in postgres
select col2 as col1, avg(col3)
from
    (select gender as col1, maritalstatus as col2,
    yearlyincome as col3 from customer) as layer_1
group by col1;
3 голосов
/ 01 октября 2010

Некоторые СУБД позволяют использовать псевдоним вместо того, чтобы повторять все выражение.
Teradata является одним из таких примеров.

Я избегаю обозначения порядкового номера в соответствии с рекомендациями Билла по причинам, задокументированным в этом вопросе SO .

Простая и надежная альтернатива - всегда повторять выражение в предложении GROUP BY.
DRY НЕ применяется к SQL.

1 голос
/ 28 апреля 2015

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

0 голосов
/ 01 октября 2010

В тот день, когда я обнаружил, что Rdb, бывший продукт DEC, теперь поддерживаемый Oracle, позволяет использовать псевдоним столбца в GROUP BY. Основной Oracle до версии 11 не позволяет использовать псевдоним столбца в GROUP BY. Не уверен, что Postgresql, SQL Server, MySQL и т. Д. Будут или не будут позволять. YMMV.

...