Question

In the table below I am storing some conditions like this:

enter image description here

Then, generally, in second table, I am having the following records:

enter image description here

and what I need is to compare these values using the right condition and store the result ( let's say '0' for false, and '1' for true in additional column).

I am going to do this in a store procedure and basically I am going to compare from several to hundreds of records.

What of the possible solution is to use sp_executesql for each row building dynamic statements and the other is to create my own scalar function and to call it for eacy row using cross apply.

Could anyone tell which is the more efficient way?

Note: I know that the best way to answer this is to make the two solutions and test, but I am hoping that there might be answered of this, based on other stuff like caching and SQL internal optimizations and others, which will save me a lot of time because this is only part of a bigger problem.

Was it helpful?

Solution

I don't see the need in use of sp_executesql in this case. You can obtain result for all records at once in a single statement:

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

and update additional column with something like:

;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

If above logic is supposed to be applied in many places, not just over one table, then yes you may think about function. Though I would used rather inline table-valued function (not scalar), because of there is overhead imposed with use of user defined scalar functions (to call and return, and the more rows to be processed the more time wastes).

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

which can be applied then as:

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

or

select f.Result
from YourAnotherTable t
    cross apply ftComparison(SomeValueColumn, SomeOtherValueColumn, @someConditionType) f
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top