我有两张桌子:
Vehicles
make model modification
Audi A 5 A 5 2010 Sportsback 2.8
Audi A 5 A 5 2012 Quattro L
Audi A 5 A 5 Cabriolet
和
matchingModel
make model modContain modEnd finalModel
Audi A 5 Sportback A5 Sportback
Audi A 5 L A5 L
Audi A 5 A5
我的任务是通过查找匹配来获得最适合的finalModel(可以在下面的选择中看到)。 首先我试图加入表格
(SELECT
matchingModel.finalModel
FROM vehicles
LEFT OUTER JOIN matchingModel ON
matchingModel.TEXT1 = vehicles.make
AND vehicles.model = nvl(matchingModel.model,vehicles.model)
AND vehicles.modification LIKE decode(matchingModel.modContain, NULL, vehicles.modification, '%'||matchingModel.modContain||'%')
AND vehicles.modification LIKE decode(matchingModel.modEnd, NULL, vehicles.modification, '%'||' '||matchingModel.modEnd)
)
AS bestMatch
但这不起作用,因为当Sportsback被发现为sportsback时,后来被覆盖为简单的A5,因为它也匹配。
接下来我简单地通过“nvling”所有可能的选项来实现这一点:nvl(nvl(nvl(选择make make,model fits和modContains位于修改中间,选项单元格为空),(选择make,模型拟合和modEnd就像修改的结束而modEnd不是空的),(选择make和model适合的地方等等))AS Bestmatch 这有效,但速度很慢(两个表都有超过500k的记录)。
这只是非常大的选择的一部分,所以很难重写这种正常的方式。 无论如何,问题是,是否有任何最佳实践如何在oracle中获得最佳匹配,只有一次,快速?我遇到的问题是性能,或者值适合两次,或者“where”子句不起作用,因为我不知道modContain或modEnd是否为空。
提前谢谢你。 对不起英文。
答案 0 :(得分:1)
现在还没有完成,但我找到了一个例子,你可以继续为自己解决问题:SQL Fiddle Demo
select * from (
(select
case when v.modification like '%'||m.modContain||'%' then 2
when m.modcontain is null then 1
else 0 end m1,
case when v.modification like '%'||m.modend then 2
when m.modend is null then 1
else 0 end m2
, m.make mmake, m.model mmodel, modcontain, modend, finalmodel
, v.make vmake, v.model vmodel, modification
from vehicles v, matchingmodel m
where
v.make = m.make
and soundex(v.model) = soundex(m.model) ) ) x
order by m1+m2 desc
因此子查询将匹配加在一起,最高匹配应该是您的最佳匹配。我还使用了soundex,它也可以帮助你,因为Sportback
和Sportsback
不完全相同,这帮助我使A5
和A 5
相同。另外,为了加快速度,你需要分配好的指标和观察解释计划,特别是如果你有500k的记录。这不是一件容易的事。
关于编写程序(这是一个好主意)未经测试的想法可能看起来像这样:
create or replace function vehicle_matching(i_vehicles vehicles%rowtype,
i_matchingmodel matchingmodel%rowtype)
return number
is
l_return number;
begin
if i_vehicles.modification like '%'||i_matchingmodel.modContain||'%' then
l_return := 3;
elsif soundex(i_vehicles.modification) like '%'||soundex(i_matchingmodel.modContain)||'%' then
l_return := 2;
...
if i_vehicles.modification like '%'||i_matchingmodel.modend then
l_return := l_return + 1; -- there is no i++ in PL/SQL
elsif
...
return l_return;
end vehicle_matching;
此外,我在考虑使用INSTR
和SUBSTR
比使用%
效率更高,但我实际上并不认为情况确实如此。
答案 1 :(得分:0)
编写查询以在任何部分匹配时返回1 然后写另一个查询以在另一个部分匹配上返回另一个 - 等等。
对所有可能计入“相似性”的列重复此操作
最后,你会发现总和(或数量)最高的行为1,这将是最接近的匹配。