1

以下の表では、次のようないくつかの条件を保存しています。

ここに画像の説明を入力

次に、通常、2 番目のテーブルには次のレコードがあります。

ここに画像の説明を入力

そして、必要なのは、正しい条件を使用してこれらの値を比較し、結果を保存することです (追加の列で、false の場合は「0」、true の場合は「1」としましょう)。

これをストア プロシージャで実行し、基本的に数から数百のレコードを比較します。

可能な解決策は、動的ステートメントを構築する各行に sp_executesql を使用することです。もう 1 つは、独自のスカラー関数を作成し、クロス適用を使用して簡単な行に対して呼び出すことです。

どちらがより効率的な方法か誰にもわかりますか?

注: これに答える最善の方法は、2 つのソリューションを作成してテストすることであることはわかっていますが、キャッシングや SQL 内部最適化などの他のものに基づいて、この答えが得られることを願っています。これはより大きな問題の一部にすぎないためです。

4

1 に答える 1

2

この場合、を使用する必要はありませんsp_executesql。1 つのステートメントで一度にすべてのレコードの結果を取得できます。

select Result = case
    when ct.Abbreviation='=' and t.ValueOne=t.ValueTwo then 1
    when ct.Abbreviation='>' and t.ValueOne>t.ValueTwo then 1
    when ct.Abbreviation='>=' and t.ValueOne>=t.ValueTwo then 1
    when ct.Abbreviation='<=' and t.ValueOne<=t.ValueTwo then 1
    when ct.Abbreviation='<>' and t.ValueOne<>t.ValueTwo then 1
    when ct.Abbreviation='<' and t.ValueOne<t.ValueTwo then 1
    else 0 end
from YourTable t
    join ConditionType ct on ct.ID = t.ConditionTypeID

次のようなもので追加の列を更新します。

;with cte as (
    select t.AdditionalColumn, Result = case
        when ct.Abbreviation='=' and t.ValueOne=t.ValueTwo then 1
        when ct.Abbreviation='>' and t.ValueOne>t.ValueTwo then 1
        when ct.Abbreviation='>=' and t.ValueOne>=t.ValueTwo then 1
        when ct.Abbreviation='<=' and t.ValueOne<=t.ValueTwo then 1
        when ct.Abbreviation='<>' and t.ValueOne<>t.ValueTwo then 1
        when ct.Abbreviation='<' and t.ValueOne<t.ValueTwo then 1
        else 0 end
    from YourTable t
        join ConditionType ct on ct.ID = t.ConditionTypeID
)
update cte
set AdditionalColumn = Result

上記のロジックが 1 つのテーブルだけでなく、多くの場所に適用されることになっている場合は、機能について考えることができます。私はかなりインラインのテーブル値関数 ( scalarではありません) を使用しますが、ユーザー定義のスカラー関数 (呼び出して返すため) を使用するとオーバーヘッドが発生し、処理する行が増えるほど時間が浪費されます)。

create function ftComparison
(
    @v1 float,
    @v2 float,
    @cType int
)
returns table
as return
    select
        Result = case
            when ct.Abbreviation='=' and @v1=@v2 then 1
            when ct.Abbreviation='>' and @v1>@v2 then 1
            when ct.Abbreviation='>=' and @v1>=@v2 then 1
            when ct.Abbreviation='<=' and @v1<=@v2 then 1
            when ct.Abbreviation='<>' and @v1<>@v2 then 1
            when ct.Abbreviation='<' and @v1<@v2 then 1
            else 0
        end
    from ConditionType ct
    where ct.ID = @cType

これは次のように適用できます。

select f.Result
from YourTable t
    cross apply ftComparison(ValueOne, ValueTwo, t.ConditionTypeID) f

また

select f.Result
from YourAnotherTable t
    cross apply ftComparison(SomeValueColumn, SomeOtherValueColumn, @someConditionType) f
于 2013-08-23T13:15:28.660 に答える