web-dev-qa-db-ja.com

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)

しかし、なぜ前者を単純に使用できないのですか?

131
Haoest

SQLは、クエリが次の順序で実行されたかのように実装されます。

  1. FROM句
  2. WHERE句
  3. GROUP BY句
  4. HAVING句
  5. SELECT句
  6. ORDER BY句

ほとんどのリレーショナルデータベースシステムでは、この順序で、前の手順で導入されている必要があるため、どの名前(列またはエイリアス)が有効であるかが説明されます。

したがって、OracleおよびSQL Serverでは、SELECT句の前にGROUP BYが実行されるため、SELECT句で定義するGROUP BY句で用語を使用できません。

ただし、例外があります。MySQLとPostgresには、それを可能にする追加のスマートさがあります。

255
Codo

エイリアスを使用できるように、常にサブクエリを使用できます。もちろん、パフォーマンスを確認してください(dbサーバーは両方を同じように実行できますが、検証するのに苦労することはありません)。

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

少なくともPostgreSQLでは、GROUP BY句の結果セットで列番号を使用できます。

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

もちろん、これをインタラクティブに行い、クエリを編集して結果の列の数または順序を変更する場合、これは苦痛になります。それでも。

15
Bill Gribble

SQL Serverでは、処理の論理的な順序のため、GROUP BY句でエイリアスを参照することはできません。 GROUP BY句はSELECT句の前に処理されるため、GROUP BY句が評価されるときにエイリアスは不明です。これは、ORDER BY句でエイリアスを使用できる理由も説明しています。

SQL Serverの論理処理フェーズ に関する情報の1つのソースを次に示します。

12
bobs

なぜそうなのかは答えていませんが、CROSS APPLYを使用してエイリアスを作成することで、SQL Serverのその制限を回避する方法を示したかっただけです。次に、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
5
Ricardo

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;
4
Shannon S

一部のDBMSでは、式全体を繰り返す必要がなく、エイリアスを使用できます。
Teradataはその一例です。

this SO question に記載されている理由により、Billが推奨する序数表記を避けています。

簡単で堅牢な代替方法は、GROUP BY句の式を常に繰り返すことです。
DRYはSQLには適用されません。

3
bernie

SQLiteのビューからの結果をグループ化するときにエイリアスを使用することに注意してください。エイリアス名が(ビューに対する)基になるテーブルの列名と同じ場合、予期しない結果が得られます。

1
GGGforce

当時、Oracleで現在サポートされている以前のDEC製品であるRdbが、GROUP BYで列エイリアスを使用できることを発見しました。バージョン11までの主流のOracleでは、GROUP BYで列エイリアスを使用できません。 Postgresql、SQL Server、MySQLなどが許可するものと許可しないものがわかりません。 YMMV。

0
Bob Jarvis