【发布时间】:2013-09-09 23:40:02
【问题描述】:
我正在尝试根据第一个表中的字符串是否包含在第二个表中的长字符串的一部分中来连接两个表。我在 SAS 中使用 PROC SQL,但也可以使用数据步骤而不是 SQL 查询。
此代码在较小的数据集上运行良好,但很快就会陷入困境,因为它必须进行大量比较。如果是简单的相等检查就好了,但必须使用index() 函数就很难了。
proc sql noprint;
create table matched as
select A.*, B.*
from search_notes as B,
names as A
where index(B.notes,A.first) or
index(B.notes,A.last)
order by names.name, notes.id;
quit;
run;
B.notes 是一个 2000 个字符(有时完全填充)的文本块,我正在寻找包含 A 中名字或姓氏的任何结果。
我认为分两步执行它并没有获得任何速度优势,因为它已经必须将 A 的每一行与 B 的每一行进行比较(因此检查名字和姓氏并不是瓶颈) .
当我运行它时,我的日志中会出现NOTE: The execution of this query involves performing one or more Cartesian product joins that can not be optimized.。使用 A=4000 个观察值和 B=100,000 个观察值运行它需要 30 分钟才能产生约 1000 个匹配项。
有什么办法可以优化吗?
【问题讨论】:
-
为了使它更像 SQL,我尝试在 A.First 和 A.Last 之前和之后添加 % ,然后使用
where B.notes LIKE A.first并产生相同的注释和相同的长运行时间。我希望使用 SQL 特性而不是 SAS 函数可以优化它,但我想不会。 -
您是在尝试左连接还是内连接,还是真正的笛卡尔积?当 B.NOTES 包含任一字段时,您是否只想将 B 中的数据连接到 A 上?
-
是的,我只想要 A 中的字段包含在 B.notes 中的结果集(接受任何一方可能有多个结果,因为多个事物可以匹配)
-
好的。让我玩弄它。这是一个棘手的问题。这在任何 SQL 处理器中都是一个问题,而不仅仅是 SAS。
-
如果它更容易,我可以确保 A.first 和 A.last 在 A 中都是唯一的(两者都是唯一的,因此也是唯一的组合)