sql - T-SQL 根据 BIT 参数值查找匹配行

标签 sql sql-server database stored-procedures

我正在尝试创建一个存储过程,该过程返回 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/

相关文章:

SQL Server 分区 - 唯一索引错误

java - PostgreSQL + Java

c# - 如何删除表中的这种冗余?

sql - 如何选择 * 除一个字段外,其他所有内容都不同的地方

database - 好的数据库设计在表中没有标识列,对吗?

php - 存储数据库信息以通过电子邮件发送

.net - 如何向客户端报告长时间运行的 PostgreSQL 函数的进度

sql - 从 DBIx::Class 中的多个表中选择

sql - 如何在表中查找值并将其插入到另一个表中?

sql - 从 win 7 上的 Aginity 工作台查找 IBM netezza sql 数据库上的表大小