SQLでは、私の知る限り、概念的な解釈順序である論理クエリの処理順序は、次のようにFROMで始まります。
このリストをたどると、エイリアスがまだ作成されていないため、WHERE句にSELECTエイリアスを設定できない理由が簡単にわかります。 T-SQL(SQL Server)はこれに厳密に従っており、SELECTを渡すまでSELECTエイリアスを使用できません。
ただし、MySQLでは、(論理的に)SELECT句の前に処理する必要がある場合でも、HAVING句でSELECTエイリアスを使用できます。これはどのようにして可能ですか?
例を挙げましょう:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
ステートメントはT-SQLでは無効です(HAVINGがSELECTエイリアスAmount
を参照しているため)...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
...しかし、MySQLでは問題なく動作します。
これに基づいて、私は疑問に思います:
まあ、この種の質問がある場合、私見の情報源はMySQLのドキュメントです。さてポイントに。これは、デフォルトで有効になっているGROUP BY
へのMySql拡張の動作です。
GROUP BYのMySQL拡張
MySQLはこの動作を拡張し、集計列のHAVING句でエイリアスを使用できるようにします
標準の動作が必要な場合は、sql_mode
ONLY_FULL_GROUP_BY
を使用してこの拡張機能を無効にできます
SET [SESSION | GLOBAL] sql_mode = ONLY_FULL_GROUP_BY;
上記のクエリをONLY_FULL_GROUP_BY
sql_modeで実行しようとすると、次のエラーメッセージが表示されます。
非グループ化フィールド 'Amount'がHAVING句で使用されています:SELECT YEAR(orderdate)、COUNT(*)as Amount FROM Orders GROUP BY YEAR(orderdate)HAVING Amount> 1
これはSQLFiddleデモです
したがって、MySQLのインスタンスを構成して使用する方法は、あなた次第です。
良い質問。
これらのクエリを実行する必要があると思います
EXPLAIN SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
SHOW WARNINGS;
クエリがどのように書き換えられたかを確認します。クエリオプティマイザーがAmountをCOUNT(*)に置き換えることを確認してください
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING COUNT(*)>1;
それのように
select
*
from
test
where
id = 5 - 3
クエリオプティマイザーの後は、このようなものです。
select
test.id as 'id'
from
test
where
test.id = 2