1

このクエリがあります(疑似コード)

SELECT 
    a = 1,
    b = 2,
    c = CASE 
            WHEN ISNULL(
                         (SELECT MONTH(GETDATE()) <---long query
                         ), 0) = 0 THEN 'found'
            ELSE 
              SELECT MONTH(GETDATE())     <--- repeated long query
        END

問題はSELECT MONTH(GETDATE())、実際には which が非常に長いクエリであることです。

この「長い式」がクエリに 2 回表示されないようにするための回避策はありますか?

ps

外部変数に計算するソリューションがありSELECT MONTH(GETDATE())ます...しかし、インラインソリューションがあるかどうかを調べようとしています。

4

4 に答える 4

5

利用可能なオプションがいくつかあります。

  • ユーザー定義関数 (UDF)
  • ビュー
  • 共通テーブル式 (CTE)
  • クロス/アウターアプライ

データがどのように処理されているかによって、どちらが最適かが決まります。あなたの質問は、提案を決定的に提供するのに十分な詳細を提供していませんが、これらは一見の価値があります.

UDF を使用するとすぐにパフォーマンスが低下する可能性があるため、注意して使用してください。私の個人的な経験則は、単純なデータ変換または数学的計算のために UDF を作成することです。関数で複雑なセットベースの操作を行うことは避けようとしており、そのためにはビューまたは CTE を好みます。

于 2012-05-17T14:59:05.553 に答える
2

あなたの例でのサブクエリの特定の使用パターンは、次のように書き直すことができます。

…
c = COALESCE(CAST(NULLIF((subquery), 0) AS varchar(10)), 'found')
…

Mikael Eriksson が彼のコメントで正しく指摘しているように、ここISNULLの代わりに使用する必要があるかもしれませんCOALESCE。これは、引数の 1 つにサブクエリが含まれておりISNULL、この場合はより効率的である可能性がある (または実際にはそうなる) ためです。この回答で。

ここに固定版があります:

…
c = ISNULL(CAST(NULLIF((subquery), 0) AS varchar(10)), 'found')
…

ただし、 2 番目の文字列 ( ) も変更する場合ISNULLは、2 番目の文字列 ( ) の長さに注意する必要があります。'found'問題は、指定された文字列の最大長 (この場合)ISNULLを含めて、2 番目の引数を最初の引数の正確な型にキャスト (試行) することです。2 番目の引数がだけではなく、 の10ようになった場合、文字列全体ではなく最初の 10 文字のみが返されます ( )。そのため、最初の引数の型も (たとえば に)変更することを忘れないでください。'NULL or zero is found''found'ISNULL'NULL or ze'varchar(20)

于 2012-05-18T06:49:51.553 に答える
1
SELECT 
    a = 1,
    b = 2,
    c = CASE 
            WHEN ISNULL([l], 0) = 0 THEN 'found'
            ELSE [l]
        END
from tbl
cross apply (
SELECT MONTH(GETDATE()) as [l]
) as [x]

また、元のクエリが実際に取得したものを表す場合 (つまり、「長い式」が null を返す場合に 1 つの値を返す場合) COALESCE、case ステートメントの代わりに使用することを検討してください。または単に使用するISNULL([l], 'found')

于 2012-05-17T19:42:44.370 に答える
-1

CTE を使用した例

;WITH CTE AS
(
    SELECT CASE WHEN ISNULL(MONTH(GETDATE()),0) = 0 
    THEN 'FOUND' ELSE  ISNULL(MONTH(GETDATE()),0) END Col1
),
SELECT a = 1,b = 2, C = col1
FROM Table1, CTE

鍵があれば、それを使って参加できます

SELECT a = 1,b = 2, C = CASE WHEN ISNULL(v.col1,0) = 0 THEN 'Found' ELSE v.col1 END
        FROM Table1 a
OUTER APPLY (SELECT ISNULL(MONTH(DateCol),0) Col1 FROM TABLEName b
                a.id = b.id) v
于 2012-05-17T15:03:31.843 に答える