次のように動作することに驚きました。
SELECT name, height * weight as inchpounds
FROM sashelp.class
HAVING inchpounds > 5000;
HAVING句はSELECT句の前に厳密に処理されると思っていたので。これは実際、私の側の誤った仮定ですか? それとも、これは SAS の SQL の実装に特有のものですか?
厳密に言えば、よく覚えていれば、SQL 標準の defineHAVING
句は、句の前に処理されますSELECT
。そのため、SELECT で定義されたエイリアスをHAVING
句で使用することはできません。
関連する質問で私の回答を参照してください: Using 'case expression column' in where clause for the order of the order of processing a SELECT
statement, which is:
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY
そのため、ほとんどの SQL インカネーションでは、そのクエリはエラーになります。MySQL は、標準からのこの逸脱を許容する例外の 1 つです (また、句でSELECT
エイリアスを使用することも許可されています)。GROUP BY
コメントで @a_horse_with_no_name が言及されているように、クエリは別の理由でもほとんどの SQL 製品で失敗します。つまり、すべての行に集計があるという意味ではHAVING
ないため、句と句GROUP BY
の両方で集計関数のみが許可されます。HAVING
SELECT
SAS SQLのドキュメントと例を見た後、上に投稿したクエリはSAS SQLで有効であり、次のように実行されるようです(標準SQLで):
SELECT name, height * weight AS inchpounds
FROM sashelp.class
WHERE height * weight > 5000;
私が正しく理解していれば、次のように、集計関数と非集計列を混在させることもできます。
SELECT name, height,
MAX(height) AS max_height
FROM sashelp.class ;
これは (標準 SQL では) 次のように評価されます。
SELECT name, height,
MAX(height) OVER () AS max_height
FROM sashelp.class ;
SQL 標準は、句が実行される順序ではなく、句が解釈される順序を指定します。実際には、これはhaving
句が の後に解析されることを意味するため、ステートメントselect
で定義された変数を使用できます。select
SAS SQL は他のダイアレクトとは異なります。句select
で変数を使用できる場合があります。where
SQL エンジンは、好きなように実際にクエリを自由に実行できます。ただし、質問はクエリの実行ではなく、解析に関するものです。
having
a のない句の使用は、group by
一般的に疑わしいものです。ただし、どの方言でも機能するはずだと思います。唯一の問題は、0 行が返されるか、1 つの集計行が返されるかです。
特にクエリが機能することは驚くべきことです。SQL のほとんどの方言では、エラーが発生します。これは、having
句が集計を意味し、 の値がselect
集計関数に含まれていないためです。これが機能する唯一の他の方言はMySQLです。これには、隠し列と呼ばれる(誤った)機能があるためです。SAS SQL は、他の方言よりも標準 SQL から少し離れています。
WHERE
SQL の「標準」について話すことはできませんが、SAS の実装に関しては、句と句の唯一の違いは、 HAVING
「いつ」それらが適用されるかです。 句は中間結果の作成 (ステートメントWHERE
にリストされた列を含む一時テーブルの作成) に適用され、句はどの行が最終テーブルに書き込まれるかを制御します。SELECT
HAVING
または、ステートメントでCALCULATED
キーワードを使用できます。WHERE
SELECT name, height * weight as inchpounds
FROM sashelp.class
WHERE CALCULATED inchpounds > 5000;
これは実際、私の側の誤った仮定ですか?
それは間違っている可能性があります。クエリ プランナーは、データベースのデータと統計情報に従って、クエリの実行方法を決定します。
特定の順序で実行されるさまざまな句について考えることは、クエリの作成と推論に役立ちますが、これはほとんどの SQL データベースが実際に機能する方法ではありません。