6

SQLクエリを作成するとき、「単一のクエリでこれを行う方法はない」とよく思います。それが起こったとき、私はしばしばストアドプロシージャまたは(ある種の)一時テーブルを使用するマルチステートメントテーブル値関数に目を向け、結果を単純に組み合わせて結果テーブルを返すことになります。

理論の問題として、単一の結果セットを単一のクエリ(複数のステートメントではなく)として返すクエリを記述できるかどうかを誰かが知っているかどうか疑問に思います。明らかに、私はコードの可読性や保守性、おそらくクエリのパフォーマンス/効率などの関連するポイントを無視しています。これは理論に関するものです-それは可能です...そして心配しないでください、マルチステートメントがすべての場合に私の目的により適しているときに、私は確かにシングルステートメントクエリを書くことを強制し始めるつもりはありませんが、単一のクエリから結果を取得するための実行可能な方法があるかどうかについて、2回または少し長く考えるようになるかもしれません。

いくつかのパラメーターが適切であると思います。一般的なベストプラクティスに従うテーブル(主キーを持つすべてのテーブルなど)を備えたリレーショナルデータベース(MS SQLなど)を考えています。

注:これで「AcceptedAnswer」を獲得するには、明確な証拠(Web資料などへの参照)を提供する必要があります。

4

5 に答える 5

3

それは可能だと思います。私は非常に難しいクエリ、非常に長いクエリを扱ってきましたが、多くの場合、単一のクエリでそれを行うことができます。ただし、ほとんどの場合、管理するのは難しいため、1つのクエリで行う場合は、クエリに注意深くコメントするようにしてください。

単一のクエリでは実行できない何かに遭遇したことはありません。
ただし、複数のクエリで実行するのが最適な場合もあります。

于 2010-01-06T18:42:59.697 に答える
2

「はい」と言いますが、それを証明することはできません。しかし、私の主な思考プロセスは次のとおりです。

  • すべての選択は、セットベースの操作である必要があります

  • あなたの仮定は、あなたが数学的に正しいセットを扱っている(すなわち正しく正規化されている)ということです

  • 集合論はそれが可能であることを保証するはずです

他の考え:

  • 複数のSELECTステートメントは、多くの場合、一時テーブル/テーブル変数をロードします。これらは、CTEで導出または分離できます。

  • RBAR処理(良いか悪いかを問わず)は、派生テーブルへのCROSS /OUTEARAPPLYで処理されるようになりました。

  • UDFは、このコンテキストでは「不正行為」として分類されます。これは、SELECTを単一のモジュールではなく別のモジュールに配置できるためです。

  • DMLの「前」シーケンスでは書き込みは許可されていません。これにより、状態がSELECTからSELECTに変更されます。

  • 当店でコードを見たことがありますか?

編集、用語集

編集:適用:不正行為?

SELECT
    *
FROM
    MyTable1 t1
    CROSS APPLY
    (
        SELECT * FROM MyTable2 t2
        WHERE t1.something = t2.something
    ) t2
于 2010-01-06T18:51:11.840 に答える
2

少なくとも最近のバージョンのOracleでは絶対に可能です。これには、SQLチューリングを完全にする「モデル句」があります。(http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/)。もちろん、これはすべて、時間とメモリに無制限がないという通常の制限があります。

これらの腹部のない通常のSQL方言の場合、それは不可能だと思います。

'normal sql'で実装する方法がわからないタスクは、次のようになります。整数型の単一列を持つテーブルを想定します。

すべての行について、'現在の行の値を取得し、その数の行に戻り、その値をフェッチし、その数の行に戻り、同じ値を2回連続してフェッチし、結果として返すまで続行します。

于 2010-01-06T18:52:34.490 に答える
2

私はそれを証明することはできませんが、あなたのデータベース設計が適切に行われていれば、答えは慎重なイエスだと思います。通常、特定の結果を得るために複数のステートメントを作成することを余儀なくされることは、スキーマにいくつかの改善が必要な可能性があることを示しています。

于 2010-01-06T18:43:09.603 に答える
1

理論的にはそうです、OUTERAPPLYまたはサブクエリの関数または厄介な迷路を使用する場合。ただし、読みやすさとパフォーマンスのために、私たちは常に一時テーブルとマルチステートメントのストアドプロシージャを使用することになりました。

上記の誰かがコメントしたように、これは通常、データ構造の匂いがし始めている兆候です。悪いことではありませんが、パフォーマンス上の理由で非正規化するときが来たのかもしれません(私たちの最善の策です)。あるいは、正規化された「実際の」データの前に非正規化されたクエリレイヤーを配置するときです。

于 2010-01-06T19:20:30.907 に答える