我正在尝试创建一个存储过程,该过程返回 person 表中特定列具有相同值的行。我希望存储过程接受参数值,例如 @match_on_forenames BIT
和 @match_on_surname BIT
。因此,例如 EXEC find_matching @match_on_forenames 1, @match_on_surname 1
会在表中找到名字和姓氏字段匹配的行,显然不匹配自身。
我有一个类似于以下的存储过程:
ALTER PROC get_matching_records
@match_on_forenames BIT,
@match_on_surname BIT
AS
SELECT DISTINCT
p.forenames, p.surname
FROM
person p
WHERE
EXISTS
(
SELECT
p1.forenames, p1.surname
FROM
person p1
WHERE
(((@match_on_forenames = 1 AND p.forenames = p1.forenames AND p.id <> p1.id)) OR @match_on_forenames = 0)
AND (((@match_on_surname = 1 AND p.surname = p1.surname AND p.id <> p1.id)) OR @match_on_surname = 0)
)
当我引入 OR @match_on_forenames
时,查询的性能变得很差。
有什么想法可以最好地解决这个问题吗?
非常感谢。
最佳答案
这是你的逻辑:
WHERE EXISTS (SELECT 1
FROM person p1
WHERE
(((@match_on_forenames = 1 AND p.forenames = p1.forenames AND p.id <> p1.id)) OR @match_on_forenames = 0)
AND (((@match_on_surname = 1 AND p.surname = p1.surname AND p.id <> p1.id)) OR @match_on_surname = 0)
)
如果没有or
速度很快,那么三个条件可能会解决问题:
WHERE (@match_on_forenames = 1 and @match_on_surname = 1 and
EXISTS (SELECT 1
FROM person p1
WHERE (p.forenames = p1.forenames AND p.id <> p1.id) AND
(p.surname = p1.surname AND p.id <> p1.id)
)
) OR
(@match_on_forenames = 0 and @match_on_surname = 1 and
EXISTS (SELECT 1
FROM person p1
WHERE (p.surname = p1.surname AND p.id <> p1.id)
)
) OR
(@match_on_forenames = 1 and @match_on_surname = 0 and
EXISTS (SELECT 1
FROM person p1
WHERE (p.forenames = p1.forenames AND p.id <> p1.id)
)
)
根据您的观察,每个 exists
子句都应该很快,因为更简单的查询更快。
关于sql - T-SQL 根据 BIT 参数值查找匹配行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30177870/