SQL クエリ理論の質問 - 単一ステートメントと複数ステートメントのクエリ
-
19-09-2019 - |
質問
SQL クエリを作成していると、「単一のクエリでこれを実行する方法はない」と思うことがよくあります。そのような場合、私は多くの場合、(何らかの種類の) 一時テーブルを使用するストアド プロシージャや複数ステートメントのテーブル値関数を使用し、最終的には単純に結果を結合して結果テーブルを返します。
単純に理論上、そうなのかどうかを誰かが知っているかどうか疑問に思っています。 すべき 単一の結果セットを単一のクエリ (複数のステートメントではなく) として返す任意のクエリを作成できます。明らかに、コードの可読性や保守性、さらにはクエリのパフォーマンスや効率などの関連点を無視しています。これは理論上の話ですが、それはできるでしょうか...心配しないでください。どのような場合でも、複数ステートメントの方が目的に適している場合に、単一ステートメントのクエリを強制的に作成するつもりはありません。単一のクエリから結果を取得する実行可能な方法があります。
いくつかのパラメータが適切であると思います。一般的なベストプラクティス(すべてのテーブルに主キーがあるなど)に従うテーブルを備えたリレーショナルデータベース(MS SQLなど)を考えています。
注記:これについて「承認された回答」を獲得するには、決定的な証拠 (Web 資料または同様のものへの参照) を提供する必要があります。
解決
少なくとも、Oracle の最新バージョンでは、それは絶対に可能です。これには、SQL チューリングを完全なものにする「モデル句」があります。( http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/ )。もちろん、これには通常の制限があり、実際には無制限の時間とメモリがあるわけではありません。
これらの我慢のない通常の SQL 方言では、それは不可能だと思います。
「通常の SQL」で実装する方法がわからないタスクは次のとおりです。整数型の列が 1 つあるテーブルを想定します。
行のすべての行について、現在の行で値を取り、多くの行を戻し、その値を取得し、多くの行を戻し、同じ値を2回連続して取得し、結果としてそれを返すまで続けます。
他のヒント
私はそれが可能であると信じています。私は非常に困難なクエリ、非常に長いクエリで働いてきた、と多くの場合、単一のクエリでそれを行うことが可能です。しかし、ほとんどの時間、それはmantainが困難ですので、あなたは、単一のクエリでそれを行うならば、あなたは慎重にあなたのクエリをコメントしてください。
私は、単一のクエリで行うことができなかった何かに遭遇したことがありません。
しかし、時にはそれが複数のクエリでそれを行うのがベストです。
私はそれを証明することはできませんが、私は答えは慎重イエスであると考えている - データベース設計が適切に行われました。通常、スキーマは、いくつかの改善を必要とするかもしれない記号は、特定の結果を得るために複数の文を書くことです余儀なくされます。
「はい」と言えますが、それを証明することはできません。ただし、私の主な思考プロセスは次のとおりです。
すべての選択はセットベースの操作である必要があります
あなたの仮定は、数学的に正しいセット(つまり、正しく正規化されたセット)を扱っていることです。
集合論はそれが可能であることを保証するはずです
他の考え:
複数の SELECT ステートメントは、多くの場合、一時テーブル/テーブル変数をロードします。これらは CTE で導出または分離できます。
RBAR 処理 (良くも悪くも) は、派生テーブルに対する CROSS/OUTER APPLY で処理されるようになりました。
UDF は、単一のモジュールではなく別のモジュールに SELECT を挿入できるため、この文脈では「不正行為」として分類されると思います。
DML の「前」シーケンスでは書き込みは許可されません。これにより、状態が SELECT から SELECT に変わります。
当店のコードを見たことがありますか?
編集、用語集
編集:適用する:浮気?
SELECT
*
FROM
MyTable1 t1
CROSS APPLY
(
SELECT * FROM MyTable2 t2
WHERE t1.something = t2.something
) t2
理論的には、はい、あなたは機能やOUTER APPLYsまたはサブクエリの拷問の迷路を使用している場合、しかし、読みやすさとパフォーマンスのために、我々は常に一時テーブルと複数文のストアドプロシージャと一緒に行くまで終了している。
上記のコメントに誰かのように、これは通常、あなたのデータ構造が臭いし始めているサインです。それは、の悪いの、だけど、それは多分それは(私たちの最高に起こる)パフォーマンス上の理由からdenormalise、または多分あなたの正規化された「本物」のデータの前にdenormalised問い合わせ層を置くための時間だではないということ。