0

I have a SQL Server table with 3 similar columns: Telephone 1, Telephone 2, and Telephone 3. User will provide a telephone number, and SQL should fetch the data in the least possible time in an optimum way from one of the 3 columns. Telephone number can exist in any of the 3 columns.

I'm thinking of one or two options:

  1. Creating a 4th column combining the 3 telephone columns. And, doing a search on the concatenated value.

  2. May be a child table with only the 3 telephone columns with a CLUSTERED index.

Is there a better way? (Im sure there's one.) I know we can do a hash of 3 columns and do a faster search. I don't know much about hash. Has anyone worked on a similar situation?

1
  • Thank you thunderblaster for editing! Commented Mar 9, 2014 at 3:33

2 Answers 2

3

Well, you can do a search by doing:

where @USERNUMBER in (telephone1, telephone2, telephone3)

However, databases in general find it difficult to optimize such queries.

The right solution is to normalize the data. That is, create a new table, maybe called something like PersonTelephones that would have, among other columns, a PersonId, and a TelephoneNumber. Then, you are not limited to just one number.

This table can be indexes on the telephone numbers to optimize searches on the column.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Gordon. It is a MS CRM database. It's COTS product. So, no scope for data model change.
0

I totally agree with other answer(s) that involve normalizing the data. That is probably the best solution. However, if you are stuck with the existing data model, you could try a stored proc like the one below. I have assumed that you are looking for an exact match.

CREATE PROC FindPersons
    @PhoneNumber VARCHAR(16)
AS
BEGIN
--Create a temp table here with a column that matches the PK 
--of your main table (the one with the 3 phone number colums).
--I'll assume that a phone number search can return multiple rows.
CREATE TABLE #Persons (
    PersonId INT NOT NULL
)

--Just in case the temp table gets populated with a lot of records.
CREATE INDEX IDX_Persons_Id ON #Persons(PersonId)

INSERT INTO #Persons
SELECT pt.PersonId
FROM PersonsTable pt
WHERE pt.Telephone1 = @PhoneNumber

--If the above statement inserts zero rows,
--try again on the 2nd phone column.
--Depending on your business needs, you may
--want to run it regardless.
IF @@ROWCOUNT = 0
BEGIN
    INSERT INTO #Persons
    SELECT pt.PersonId
    FROM PersonsTable pt
    WHERE pt.Telephone2 = @PhoneNumber

    --If the above statement inserts zero rows,
    --try again on the 3rd phone column.
    --Depending on your business needs, you may
    --want to run it regardless.
    IF @@ROWCOUNT = 0
    BEGIN
        INSERT INTO #Persons
        SELECT pt.PersonId
        FROM PersonsTable pt
        WHERE pt.Telephone3 = @PhoneNumber
    END
END

--Select data from the main table.
SELECT pt.*
FROM PersonsTable pt
--PK column from main table is indexed.  The join should perform efficiently.
JOIN #Persons p
    ON p.PersonId = pt.PersonId

END

2 Comments

Oh, and it goes without saying that you will have indexes on Telephone1, Telephone2, and Telephone3.
Thank you DMason for the script.

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.