Join Issue

  • I thought there is a concept of "short-circuiting" in sql server. Try the following.

    SELECT 1 WHERE (1 = 1) OR (1 / 0 = 0)

    even if there is a division by zero still it works, because the second part never gets evaluated. Thats how probably all programming languages work to improve the performance.

    based on this understanding I thought the second part will only be evaluated if we don't have a match for the first part.

    I don't need to try the statement you gave as I know exact result even without running it.

    It has nothing to do with "short-circuiting" concept. Try:

    SELECT 1 WHERE (1 / 0 = 0) OR (1 = 1)

    Based on your understanding it should return error, but it doesn't The first part is never evaluated!

    Also would like to mention that is definitely not all programming languages implement "short-circuiting" concept to improve the performance. As you can see from above example SQL goes even futher with that: it implements "check the simplest thing first" concept 😀

    Actually, my example may not always work. It is all depend which road the sql optimiser will take.

    Some time you can see "short-circuiting" effect even where not expected, some time it doesn't work at all. For example: there is possibility to have "division by zero" error in the following query:

    SELECT Col1/Col2 FROM Table WHERE Col2 <> 0.

    SQL Server optimiser may try to calculated everything first before applying the filter and that will result into error!

    And again, all the above has nothing to do how JOIN's work. You need to read BoL to understand what the JOIN's do ion SQL, there is no much point to guess...

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Thanks for the reply Eugene. It was quite informative. Now I can say, I understand the joins some what better. Thanks.

    Any ways, if we go back to the original question of implementing the priority join and I have 4-5 OR conditions in it, then how I can do that in a simpler way?

    Regards,
    Pravasis

  • Could you please specify all conditions you have

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (5/29/2012)


    Could you please specify all conditions you have

    expanding the same sql

    select s.id, s.name1,s.name2,s.name3,s.name4,d.[desc]

    from dbo.Test_Join_Source s

    inner join dbo.Test_Join_Destination d

    on (s.name1=d.name1 or s.name2=d.name2 or s.name3=d.name3 or s.name4=d.name4)

    Regards,
    Pravasis

  • and what is the priority of your rules? which record from destination table you want to select first?

    the one with minimum id where any of the names match or the one where most of names matches?

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (5/29/2012)


    and what is the priority of your rules? which record from destination table you want to select first?

    the one with minimum id where any of the names match or the one where most of names matches?

    It should start joining from name1 to name4. If it finds a match for any of names then it should pick the desc for the first available record in destination table and go to the next record in the source table.

    Sounds like cursor or may be a function.

    Regards,
    Pravasis

  • Pravasis (5/29/2012)


    Eugene Elutin (5/29/2012)


    and what is the priority of your rules? which record from destination table you want to select first?

    the one with minimum id where any of the names match or the one where most of names matches?

    It should start joining from name1 to name4. If it finds a match for any of names then it should pick the desc for the first available record in destination table and go to the next record in the source table.

    Sounds like cursor or may be a function.

    How to determine "the first available record in destination table"? Is it the one with minimal ID?

    It's definitely not a candidate for cursor or function. It can be easily done in SET-BASED operation (and that is exactly T-SQL language was designed for)

    You can try the following (record with minimal ID's will be picked up from destination table)

    select s.id, s.name1,s.name2,

    (select top 1 d.[desc]

    from dbo.Test_Join_Destination2 d

    where (d.name1 = s.name1)

    or (d.name2 = s.name2)

    or (d.name3 = s.name3)

    or (d.name4 = s.name4)

    order by d.id) as [desc]

    from dbo.Test_Join_Source2 s

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Great, thats is probably the best solution where in we can limit the number of records as that of source table and get the desired result. Thanks Eugene.

    I guess this would evaluate record-by-record, is not it?

    If it is, is there any way we can do it in SETS.

    Any ways, thanks.

    Regards,
    Pravasis

  • It is done in SETS, using correlated sub-query.

    There is another way:

    ;with allrules

    as

    (

    select s.id, s.name1,s.name2,d.[DESC]

    ,d.id did

    from dbo.Test_Join_Source2 s

    join dbo.Test_Join_Destination2 d

    on (s.name1=d.name1)

    or (s.name2 = d.name2)

    or (d.name3 = s.name3)

    or (d.name4 = s.name4)

    )

    , mrule

    AS

    (

    select id, MIN(did) as mdid

    from allrules

    group by id

    )

    select a.id, a.name1,a.name2, a.[DESC]

    from allrules a

    join mrule m on m.id = a.id and m.mdid = a.did

    Run both to see difference in performance.

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • or a bit smaller:

    ;with allrules

    as

    (

    select s.id, min (d.id) mdid

    from dbo.Test_Join_Source2 s

    join dbo.Test_Join_Destination2 d

    on (s.name1=d.name1)

    or (s.name2 = d.name2)

    or (d.name3 = s.name3)

    or (d.name4 = s.name4)

    group by s.id

    )

    select s.id, s.name1, s.name2, d.[DESC]

    from dbo.Test_Join_Source2 s

    join allrules a

    on a.id = s.id

    join dbo.Test_Join_Destination2 d

    on d.id = a.mdid

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Thanks you all.

    That was really helpful.Appreciate it.

    Regards,
    Pravasis

Viewing 11 posts - 16 through 25 (of 25 total)

You must be logged in to reply to this topic. Login to reply