1

I have a table with Addresses and Organization Names. There are instances where the same address can be associated with multiple organizations, and other instances where there are multiple records for the same Address-Organization pair. To wit:

Address    Orgname
Address1   Orgname1
Address2   Orgname2
Address2   Orgname2
Address3   Orgname3
Address3   Orgname4

I would like to run a select query which outputs 1 row for each Address, and if there is a 1:1 Address:Orgname relationship, the orgname, otherwise the word 'Multiple'. To wit:

Address    Orgname
Address1   Orgname1
Address2   Orgname2
Address3   Multiple

I wrote the following to accomplish this, but it runs extremely slow and I would like to know how to optimize it. Subquery X returns the distinct Match Address:Orgname. Subquery Y counts the remaining and returns the addresses where there is a 1:many relationship. These run fast on their own. The outer query then goes back to the original table and returns the distinct Address and Orgname if the address is not in the subquery of addresses with 1:many relationship, or 'Multiple' if it is.

SELECT DISTINCT [Match Address], 
CASE WHEN [Match Address] in 
    (SELECT y.[Match Address] from 
        (SELECT x.[Match Address], count(x.ORGNAME) as [Count] from
            (SELECT DISTINCT [Match Address], ORGNAME
            FROM Table) x
        GROUP BY [Match Address]
        HAVING count(x.ORGNAME) > 1) y)
THEN 'Multiple' ELSE ORGNAME END as ORGNAME
FROM Table

I suspect that instead of putting the subquery in memory and treating it as a table for the outer query, it's using a nested loop and re-running the subquery for each record in the table. I'm just not experienced enough to know how to prevent this from happening.

2
  • What does the execution plan show? Commented Apr 20, 2018 at 16:33
  • fyi, you might have better luck posting this on dba.stackexchange.com instead. Commented Apr 20, 2018 at 16:33

1 Answer 1

4

I think it is easier to write the query as:

select address,
       (case when min(orgname) = max(orgname) then min(orgname)
             else 'Multiple'
        end) as orgname
from t
group by address;
Sign up to request clarification or add additional context in comments.

1 Comment

This is the one. <2 seconds on 68k rows. Good logic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.