次のように動作することに驚きました。
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 SELECTstatement, 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の両方で集計関数のみが許可されます。HAVINGSELECT
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で定義された変数を使用できます。selectSAS SQL は他のダイアレクトとは異なります。句selectで変数を使用できる場合があります。where
SQL エンジンは、好きなように実際にクエリを自由に実行できます。ただし、質問はクエリの実行ではなく、解析に関するものです。
havinga のない句の使用は、group by一般的に疑わしいものです。ただし、どの方言でも機能するはずだと思います。唯一の問題は、0 行が返されるか、1 つの集計行が返されるかです。
特にクエリが機能することは驚くべきことです。SQL のほとんどの方言では、エラーが発生します。これは、having句が集計を意味し、 の値がselect集計関数に含まれていないためです。これが機能する唯一の他の方言はMySQLです。これには、隠し列と呼ばれる(誤った)機能があるためです。SAS SQL は、他の方言よりも標準 SQL から少し離れています。
WHERESQL の「標準」について話すことはできませんが、SAS の実装に関しては、句と句の唯一の違いは、 HAVING「いつ」それらが適用されるかです。 句は中間結果の作成 (ステートメントWHEREにリストされた列を含む一時テーブルの作成) に適用され、句はどの行が最終テーブルに書き込まれるかを制御します。SELECTHAVING
または、ステートメントでCALCULATEDキーワードを使用できます。WHERE
SELECT name, height * weight as inchpounds
FROM sashelp.class
WHERE CALCULATED inchpounds > 5000;
これは実際、私の側の誤った仮定ですか?
それは間違っている可能性があります。クエリ プランナーは、データベースのデータと統計情報に従って、クエリの実行方法を決定します。
特定の順序で実行されるさまざまな句について考えることは、クエリの作成と推論に役立ちますが、これはほとんどの SQL データベースが実際に機能する方法ではありません。