我有两个SQL表,其密钥基于First_Name,Last_Name&出生日期。 我正在尝试编写一个简单的transact sql来查找Table2中找不到Table1 Patient_Key的异常
表1包含152758条记录,并且每月都是一个新数据集 表2包含8388条记录并将继续增长
所以我现在的查询需要花费半小时才能返回零结果(我知道由于为不同的Patient_Keys分别手动查询每个表,因此没有结果 以下是查询:
SELECT T1.*
FROM TABLE1 T1
WHERE upper(T1.FIRST_NAME) + UPPER(t1.LAST_NAME) +
REPLACE(CONVERT(VARCHAR (10), T1.DATE_OF_BIRTH, 120), '-','') NOT IN
(SELECT DISTINCT upper(T2.FIRST_NAME) + UPPER(T2.LAST_NAME) +
REPLACE(CONVERT(VARCHAR (10), T2.DATE_OF_BIRTH, 120), '-','')
FROM TABLE2 T2)
是否有更高效的SQL成本节省方法?
答案 0 :(得分:4)
我建议left join
:
SELECT T1.*
FROM TABLE1 T1 LEFT JOIN
TABLE2 T2
ON t1.first_name = t2.first_name AND
t1.last_name = t2.last_name AND
t1.date_of_birth = t2.date_of_birth
WHERE t2.first_name IS NULL;
查询的问题是连接。如果您所处的环境具有区分大小写的排序规则,则应在两个表中添加单个大小写的计算列。
对于此查询,请在table2(first_name, last_name, date_of_birth)
上创建索引。这应该可以为您提供所需的性能。
答案 1 :(得分:2)
检查多个键之间存在的行与WHERE NOT EXISTS
相关子查询相比效果更好:
SELECT *
FROM Table1 T1
WHERE NOT EXISTS (
SELECT 1
FROM Table2 T2
WHERE T2.FIRST_NAME = T1.FIRST_NAME
AND T2.LAST_NAME = T1.LAST_NAME
AND T2.DATE_OF_BIRTH = T1.DATE_OF_BIRTH
)
如果您的数据库实际配置为使用区分大小写的排序规则,则应使用COLLATE
选项强制执行不区分大小写的比较。效率明显提高。无论您的配置如何,都应该有一个等效的不区分大小写的排序规则。
SELECT *
FROM Table1 T1
WHERE NOT EXISTS (
SELECT 1
FROM Table2 T2
WHERE T2.FIRST_NAME = T1.FIRST_NAME COLLATE SQL_Latin1_General_CP1_CI_AS
AND T2.LAST_NAME = T1.LAST_NAME COLLATE SQL_Latin1_General_CP1_CI_AS
AND T2.DATE_OF_BIRTH = T1.DATE_OF_BIRTH
)
如果您在Table1 (FIRST_NAME, LAST_NAME, DATE_OF_BIRTH)
和Table2 (FIRST_NAME, LAST_NAME, DATE_OF_BIRTH)
上有索引,那么您的表现应该会更好。
答案 2 :(得分:0)
避免转换和连接
;WITH NotInT2 AS (
SELECT first_name, last_name, date_of_birth
FROM t1
EXCEPT
SELECT first_name, last_name, date_of_birth
FROM t2
)
SELECT *
FROM t1
JOIN NotInT2
ON NotInT2.first_name = t1.first_name
AND NotInT2.last_name = t1.last_name
AND NotInT2.date_of_birth = t1.date_of_birth
此外,如果有必要,只使用UPPER()
功能