1

数日前に SELECT ステートメントの論理処理順序、より具体的にはエイリアスと where 句について尋ねられましたが、1 つの問題についてはわかりません。次のようなクエリがあるとします。

SELECT name AS first_name
FROM people
WHERE first_name = 'Alan';

WHERE 句でエイリアスを使用するとエラーが発生する理由は、実際には SELECT ステートメントの論理的な処理順序、または構文解析の問題でしょうか、それとも SQL 標準のルールでしょうか?

4

1 に答える 1

3

これは、SQL 標準の規則です (SQL のユーザーがおそらく考えていない多くの詳細が含まれているため、かなり複雑です)。

ルールの背後には 2 つの原則があります。having1 つ目は、論理的に必要な場合 (たとえば、句は の後に論理的に処理する必要がある場合) を除いて、標準が操作の順序付けを課していないことgroup byです。これが、SQL は結果が記述される記述言語であるという概念の基礎です。特定のデータベース エンジンは、独自の実行パスを決定できます。

2 つ目の原則は、あいまいさを避けることです。ここで、SQL コンパイラがいつ認識できるかを定義するスコープ規則が登場します。

次のステートメントを検討してください。

select a as b, b as a, a + 1 as d
-----------------------^
from t

問題は、どちらaが表の列または の列( としてエイリアス化されている) をa+1参照するかです。標準によれば、これは明確です。列の別名は、それらが定義されている句では認識されません。abaselectselect

これはwhere、同じスコープで評価される句にも適用されます。同じ例を考えてみましょう:

select a as b, b as a, a + 1 as d
from t
where a > 100

a条件はどれをwhere指しますか? 基準は明確です。このwhere句は、 の列の別名を認識しませんselect。これは、が のselect後に (論理的に) 評価されるためwhereです。だから、あなたが言うとき:

select row_number() over (order by a) as seqnum
from t
where a > 100

The value returned from the first a after 100. 列挙は最初に行われず、フィルター処理された行はフィルター処理されたシーケンス番号を取得します。

于 2014-02-20T12:05:17.763 に答える