SQL - использование псевдонима в группе по



просто любопытно о синтаксисе 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)


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

794   9  

9 ответов:

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

  1. из п.
  2. где пункт
  3. группа по предложению
  4. имея предложение
  5. выберите пункт
  6. ORDER BY clause

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

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

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

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

SELECT ItemName, FirstLetter, COUNT(ItemName)
FROM (
    SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
    FROM table1
    ) ItemNames
GROUP BY ItemName, FirstLetter

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

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

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

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

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

внимание, что использование псевдонима в Group By (для служб, которые его поддерживают, например postgres) может иметь непреднамеренные результаты. Например, если вы создадите псевдоним, который уже существует во внутреннем операторе, группа 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;

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

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

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

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

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

Я не отвечаю, почему это так, но только хотел показать способ обойти это ограничение в 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

Comments

    Ничего не найдено.