从SQL Server中的多个相同类型的列中获取数据。

时间:2014-03-06 02:34:51

标签: sql sql-server tsql

我有一个包含3个相似列的SQL Server表:Telephone 1Telephone 2Telephone 3。用户将提供一个电话号码,SQL应该在最短的时间内从3列中的一列获取数据。电话号码可以存在于3列中的任何一列中。

我正在考虑一两个选项:

  1. 创建组合3个电话列的第4列。并且,搜索连接值。

  2. 可能是一个子表,只有3个电话列具有CLUSTERED索引。

  3. 有更好的方法吗? (我确定有一个。) 我知道我们可以做3列的哈希并进行更快的搜索。我对哈希知之甚少。有没有人在类似情况下工作过?

2 个答案:

答案 0 :(得分:3)

嗯,你可以这样做:

where @USERNUMBER in (telephone1, telephone2, telephone3)

但是,数据库通常很难优化此类查询。

正确的解决方案是规范化数据。也就是说,创建一个新表,可能称为PersonTelephones,其中包括PersonIdTelephoneNumber。然后,您不仅限于一个数字。

表可以是电话号码上的索引,以优化对列的搜索。

答案 1 :(得分:0)

我完全同意其他涉及规范化数据的答案。这可能是最好的解决方案。 但是,如果您坚持使用现有数据模型,则可以尝试使用下面的存储过程。 我假设您正在寻找完全匹配。

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