【发布时间】:2017-10-12 10:49:07
【问题描述】:
我正在尝试比较 2 个不同表中的名称。
在Table1 中,该字段称为Name1,其值类似于Lynn Smith。
在Table2 中,该字段称为Name2,其值类似于Lynn Smith (Extra)
如何在忽略括号中的文本的情况下比较两个名称值? 我想写一个查询,其中我需要一些其他主要名称相同的字段。
【问题讨论】:
标签: sql sql-server tsql sql-server-2014
我正在尝试比较 2 个不同表中的名称。
在Table1 中,该字段称为Name1,其值类似于Lynn Smith。
在Table2 中,该字段称为Name2,其值类似于Lynn Smith (Extra)
如何在忽略括号中的文本的情况下比较两个名称值? 我想写一个查询,其中我需要一些其他主要名称相同的字段。
【问题讨论】:
标签: sql sql-server tsql sql-server-2014
一种方法是使用like:
select . . .
from t1 join
t2
on t2.name2 like t1.name1 + ' (%)';
但是,这可能效率不高。如果您想要性能,您可以将名称提取到第二个表中的单独列中并在其上创建索引:
alter table t2 add column name_cleaned as
(left(name2, charindex(' (', name2 + ' (') - 2));
create index idx_t2_name_cleaned on t2(name_cleaned);
然后您可以将查询表述为:
select . . .
from t1 join
t2
on t2.name2_cleaned = t1.name1;
【讨论】:
一种方法是在一侧清理后直接比较名称。 与 Gordon 的回答不同,我将使用另一个包含要从 table2 进行比较的数据的表来执行此操作。
SELECT Table2Id, Name2, NULL as cleanedName INTO NewTable FROM Table2
现在我们更新 cleanName 列以从 Name2 列中去除额外信息,如下所示。您也可以在此表上创建索引。
UPDATE cleanedName
SET cleanedName = LEFT (name2,CHARINDEX('(',Name2))
现在在 CleanedName 列上删除并重新创建索引,然后与 Table1.Name1 列进行比较
【讨论】:
如果 Table2 Column2 中的所有值在第二个名称的末尾和第一个(左)括号之间都有空格,那么你可以使用这个:
SELECT SUBSTRING('Lynn Smith (Extra)',1,PATINDEX('%(%','Lynn Smith (Extra)')-2)
如果您要将“Lynn Smith (Extra)”替换为列名:
SELECT SUBSTRING('name2',1,PATINDEX('%(%','name2')-2)
然后它将显示 name2 中的值列表,而括号中没有文本,换句话说,其格式与 table1 上 name1 中的名称相同。
SUBSTRING 和 PATINDEX 是字符串函数。
SUBSTRING 要求三个“参数”:(1) 表达式 (2) 开始和 (3) 长度。
(1) 正如您在上面看到的,第一个参数可以是(除其他外) 常量 - 'Lynn Smith (Extra)' 或列 - 'name2'
(2) 你想要的结果的开始,在这个例子中,第一个(或左边) 列或常量中字符串中的字符由数字 1 表示。
(3) 你想在结果中看到多少个字符?在此示例中,我使用 PATINDEX 创建了一个数字(见下文)。
PATINDEX 要求两个参数:(1) %pattern% 和 (2) 表达式
(1) 是您正在查找的字符或字符组(形状或“图案”) 要定位,通配符 %% 的原因 模式是因为模式的两边都可能有字符
(2) 是(除其他外)包含模式的常量或列 从论点 1.
虽然 SUBSTRING 返回字符数据(字符串的一部分),但 PATINDEX 生成一个数字,该数字是模式中的第一个字符(以数字形式给出,从表达式的左侧开始计数)。
【讨论】: