在具有大量变量的 Oracle 中使用 LIKE
Use of LIKE in Oracle with high number of variables
在 Oracle 数据库上,我有一些单独的查询,我想根据搜索词中的替换添加这些查询。考虑每个词都可以有它的词替换和附加的同义词替换。例如,单词 4MULA 具有公式、fourmula 等单词替换。 VIEW 一词有 view、vu 等词替换,而 Education 有 university、college、school 等同义词
where的结构顺序如下(3个字):
select *
from dual
where name like '%4MULA VIEW%' || ' %UNIVERSITY% '
每个单词都必须用所有可能的值来替换它。我已经完成了单独的查询,但是我有过多的查询(大约 500 个单独的查询替换了所有可能的替换)。例如,另一个单独的查询是:
select *
from dual
where name like '%FOURMULA VU%' || ' %SCHOOL% '
最终查询次数取决于排列总数:
FORMULA VIEW UNIVERSITY
4MULA VIEW UNIVERSITY
FOURMULA VIEW UNIVERSITY
FORMULA VU UNIVERSITY
4MULA VU UNIVERSITY
FOURMULA VU UNIVERSITY
...
FOURMULA VU SCHOOL
为了优化时间,我使用 OR 条件添加了所有可能的排列。例如,我添加如下:
select *
from dual
where name like '%4MULA VIEW%' || ' %UNIVERSITY% '
OR name like '%FOURMULA VU%' || ' %SCHOOL% '
...
OR name like '%FOURMULA VU%' || ' %SCHOOL '
在单个查询中添加所有排列的最佳方法是什么?
我的建议是构建一个数据集,其中包含您想在单独的 table 中搜索的值,例如 company_name(这里我列出了 [=32= 的可能组合] 和 substitution_values ('4MULA','FOURMULA'),('4MULA','FORMULA') 等
在下一个区块行业。列出了行业的值和相应的替代值。
之后,我通过 a.base_word <> b.base_word
的连接对 company_name 和行业之间的可能排列进行串联
下一步是工业区块的餐饮产品。
在此之后,块 concat_string 中的数据包含构成我的 'LIKE' 条件的可能值。
然后我继续在主要 table 条件中使用 LIKE 作为名称 LIKE
with company_name
as (select '4MULA' as base_word,'FOURMULA' as substitution_val from dual union all
select '4MULA','FORMULA' from dual union all
select 'VIEW' ,'VU' from dual union all
select 'VIEW' ,'view' from dual union all
select 'VIEW' ,'VIEW' from dual
)
,industry
as (
select 'Education' as base_word, 'UNIVERSITY' as name from dual union all
select 'Education' as base_word, 'SCHOOL' from dual union all
select 'Education' as base_word, 'COLLEGE' from dual
)
,concat_string
as (
select '%'||a.substitution_val||'%'||b.substitution_val||'%'||'%'||c.name||'%' as concat_val
--,a.*
-- ,b.*
from company_name a
join company_name b
on a.base_word <> b.base_word
join industry c
on 1=1
)
select *
from dual a
join concat_string b
on 1=1
where 'FORMULA VIEW SCHOOL' like b.concat_val
正在添加数据库 fiddle link
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=bfcc5f4844503979475af2e1a1b3f062
您可以使用对象类型和集合为每个单词创建一个同义词列表,然后创建一个用户定义的函数来处理替换:
Oracle 设置:
CREATE TYPE wordlist IS TABLE OF VARCHAR2(30);
CREATE TYPE word_synonyms IS OBJECT(
word VARCHAR2(30),
synonyms wordlist
);
CREATE TYPE word_synonyms_list IS TABLE OF word_synonyms;
CREATE FUNCTION replace_synonyms(
text IN VARCHAR2,
synonym_list IN word_synonyms_list
) RETURN VARCHAR2 DETERMINISTIC
IS
p_text VARCHAR2(4000) := text;
BEGIN
FOR i IN 1 .. synonym_list.COUNT LOOP
FOR j IN 1 .. synonym_list(i).synonyms.COUNT LOOP
p_text := REGEXP_REPLACE(
p_text,
'(^|[^a-z0-9])' || synonym_list(i).synonyms(j) || '($|[^a-z0-9])',
'' || synonym_list(i).word || '',
1,
0,
'i'
);
-- Handle repeated synonyms.
p_text := REGEXP_REPLACE(
p_text,
'(^|[^a-z0-9])' || synonym_list(i).synonyms(j) || '($|[^a-z0-9])',
'' || synonym_list(i).word || '',
1,
0,
'i'
);
END LOOP;
END LOOP;
RETURN p_text;
END;
/
测试数据:
CREATE TABLE test_data ( text ) AS
SELECT 'FORMULA VIEW UNIVERSITY' FROM DUAL UNION ALL
SELECT '4MULA VIEW UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FOURMULA VIEW UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FORMULA VU UNIVERSITY' FROM DUAL UNION ALL
SELECT '4MULA VU UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FOURMULA VU UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FOURMULA VU SCHOOL' FROM DUAL UNION ALL
SELECT 'FOURMULAE VULCAN SCHOOLING' FROM DUAL;
查询:
SELECT text,
replace_synonyms(
text,
word_synonyms_list(
word_synonyms( '4MULA', wordlist( 'formula', 'fourmula' ) ),
word_synonyms( 'VIEW', wordlist( 'vu' ) ),
word_synonyms( 'UNIVERSITY', wordlist( 'school' ) )
)
) AS substitutions
FROM test_data
输出:
TEXT | SUBSTITUTIONS
:------------------------- | :-------------------------
FORMULA VIEW UNIVERSITY | 4MULA VIEW UNIVERSITY
4MULA VIEW UNIVERSITY | 4MULA VIEW UNIVERSITY
FOURMULA VIEW UNIVERSITY | 4MULA VIEW UNIVERSITY
FORMULA VU UNIVERSITY | 4MULA VIEW UNIVERSITY
4MULA VU UNIVERSITY | 4MULA VIEW UNIVERSITY
FOURMULA VU UNIVERSITY | 4MULA VIEW UNIVERSITY
FOURMULA VU SCHOOL | 4MULA VIEW UNIVERSITY
FOURMULAE VULCAN SCHOOLING | FOURMULAE VULCAN SCHOOLING
和:
SELECT text
FROM test_data
WHERE replace_synonyms(
text,
word_synonyms_list(
word_synonyms( '4MULA', wordlist( 'formula', 'fourmula' ) ),
word_synonyms( 'VIEW', wordlist( 'vu' ) ),
word_synonyms( 'UNIVERSITY', wordlist( 'school' ) )
)
)
LIKE '%4MULA VIEW%%UNIVERSITY%'
输出:
| TEXT |
| :----------------------- |
| FORMULA VIEW UNIVERSITY |
| 4MULA VIEW UNIVERSITY |
| FOURMULA VIEW UNIVERSITY |
| FORMULA VU UNIVERSITY |
| 4MULA VU UNIVERSITY |
| FOURMULA VU UNIVERSITY |
| FOURMULA VU SCHOOL |
db<>fiddle here
Currently, in test_data table I'd have just a record such as FORMULA VIEW UNIVERSITY
. In addition, I have a table for word substitution and synonyms in very similar fashion you included. Considering I have just the record FORMULA VIEW UNIVERSITY
how could I invoke replace_synonyms such as: SELECT text FROM test_data WHERE replace_synonyms(...)) LIKE '%4MULA VU%%UNIVERSITY%'
. Notice that usually I will want to compare a new name which is not in test_data as the case of '%4MULA VU%%UNIVERSITY%'
交换它,以便同义词在 LIKE
过滤器中而不是在 table:
的文本中标准化
CREATE TABLE test_data ( text ) AS
SELECT 'FORMULA VIEW UNIVERSITY' FROM DUAL;
然后:
SELECT text
FROM test_data
WHERE text LIKE replace_synonyms(
'%4MULA VU%%SCHOOL%',
word_synonyms_list(
word_synonyms( 'FORMULA', wordlist( '4mula', 'fourmula' ) ),
word_synonyms( 'VIEW', wordlist( 'vu' ) ),
word_synonyms( 'UNIVERSITY', wordlist( 'school' ) )
)
)
输出:
| TEXT |
| :---------------------- |
| FORMULA VIEW UNIVERSITY |
db<>fiddle here
在 Oracle 数据库上,我有一些单独的查询,我想根据搜索词中的替换添加这些查询。考虑每个词都可以有它的词替换和附加的同义词替换。例如,单词 4MULA 具有公式、fourmula 等单词替换。 VIEW 一词有 view、vu 等词替换,而 Education 有 university、college、school 等同义词
where的结构顺序如下(3个字):
select *
from dual
where name like '%4MULA VIEW%' || ' %UNIVERSITY% '
每个单词都必须用所有可能的值来替换它。我已经完成了单独的查询,但是我有过多的查询(大约 500 个单独的查询替换了所有可能的替换)。例如,另一个单独的查询是:
select *
from dual
where name like '%FOURMULA VU%' || ' %SCHOOL% '
最终查询次数取决于排列总数:
FORMULA VIEW UNIVERSITY
4MULA VIEW UNIVERSITY
FOURMULA VIEW UNIVERSITY
FORMULA VU UNIVERSITY
4MULA VU UNIVERSITY
FOURMULA VU UNIVERSITY
...
FOURMULA VU SCHOOL
为了优化时间,我使用 OR 条件添加了所有可能的排列。例如,我添加如下:
select *
from dual
where name like '%4MULA VIEW%' || ' %UNIVERSITY% '
OR name like '%FOURMULA VU%' || ' %SCHOOL% '
...
OR name like '%FOURMULA VU%' || ' %SCHOOL '
在单个查询中添加所有排列的最佳方法是什么?
我的建议是构建一个数据集,其中包含您想在单独的 table 中搜索的值,例如 company_name(这里我列出了 [=32= 的可能组合] 和 substitution_values ('4MULA','FOURMULA'),('4MULA','FORMULA') 等
在下一个区块行业。列出了行业的值和相应的替代值。
之后,我通过 a.base_word <> b.base_word
的连接对 company_name 和行业之间的可能排列进行串联下一步是工业区块的餐饮产品。
在此之后,块 concat_string 中的数据包含构成我的 'LIKE' 条件的可能值。
然后我继续在主要 table 条件中使用 LIKE 作为名称 LIKE
with company_name
as (select '4MULA' as base_word,'FOURMULA' as substitution_val from dual union all
select '4MULA','FORMULA' from dual union all
select 'VIEW' ,'VU' from dual union all
select 'VIEW' ,'view' from dual union all
select 'VIEW' ,'VIEW' from dual
)
,industry
as (
select 'Education' as base_word, 'UNIVERSITY' as name from dual union all
select 'Education' as base_word, 'SCHOOL' from dual union all
select 'Education' as base_word, 'COLLEGE' from dual
)
,concat_string
as (
select '%'||a.substitution_val||'%'||b.substitution_val||'%'||'%'||c.name||'%' as concat_val
--,a.*
-- ,b.*
from company_name a
join company_name b
on a.base_word <> b.base_word
join industry c
on 1=1
)
select *
from dual a
join concat_string b
on 1=1
where 'FORMULA VIEW SCHOOL' like b.concat_val
正在添加数据库 fiddle link https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=bfcc5f4844503979475af2e1a1b3f062
您可以使用对象类型和集合为每个单词创建一个同义词列表,然后创建一个用户定义的函数来处理替换:
Oracle 设置:
CREATE TYPE wordlist IS TABLE OF VARCHAR2(30);
CREATE TYPE word_synonyms IS OBJECT(
word VARCHAR2(30),
synonyms wordlist
);
CREATE TYPE word_synonyms_list IS TABLE OF word_synonyms;
CREATE FUNCTION replace_synonyms(
text IN VARCHAR2,
synonym_list IN word_synonyms_list
) RETURN VARCHAR2 DETERMINISTIC
IS
p_text VARCHAR2(4000) := text;
BEGIN
FOR i IN 1 .. synonym_list.COUNT LOOP
FOR j IN 1 .. synonym_list(i).synonyms.COUNT LOOP
p_text := REGEXP_REPLACE(
p_text,
'(^|[^a-z0-9])' || synonym_list(i).synonyms(j) || '($|[^a-z0-9])',
'' || synonym_list(i).word || '',
1,
0,
'i'
);
-- Handle repeated synonyms.
p_text := REGEXP_REPLACE(
p_text,
'(^|[^a-z0-9])' || synonym_list(i).synonyms(j) || '($|[^a-z0-9])',
'' || synonym_list(i).word || '',
1,
0,
'i'
);
END LOOP;
END LOOP;
RETURN p_text;
END;
/
测试数据:
CREATE TABLE test_data ( text ) AS
SELECT 'FORMULA VIEW UNIVERSITY' FROM DUAL UNION ALL
SELECT '4MULA VIEW UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FOURMULA VIEW UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FORMULA VU UNIVERSITY' FROM DUAL UNION ALL
SELECT '4MULA VU UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FOURMULA VU UNIVERSITY' FROM DUAL UNION ALL
SELECT 'FOURMULA VU SCHOOL' FROM DUAL UNION ALL
SELECT 'FOURMULAE VULCAN SCHOOLING' FROM DUAL;
查询:
SELECT text,
replace_synonyms(
text,
word_synonyms_list(
word_synonyms( '4MULA', wordlist( 'formula', 'fourmula' ) ),
word_synonyms( 'VIEW', wordlist( 'vu' ) ),
word_synonyms( 'UNIVERSITY', wordlist( 'school' ) )
)
) AS substitutions
FROM test_data
输出:
TEXT | SUBSTITUTIONS :------------------------- | :------------------------- FORMULA VIEW UNIVERSITY | 4MULA VIEW UNIVERSITY 4MULA VIEW UNIVERSITY | 4MULA VIEW UNIVERSITY FOURMULA VIEW UNIVERSITY | 4MULA VIEW UNIVERSITY FORMULA VU UNIVERSITY | 4MULA VIEW UNIVERSITY 4MULA VU UNIVERSITY | 4MULA VIEW UNIVERSITY FOURMULA VU UNIVERSITY | 4MULA VIEW UNIVERSITY FOURMULA VU SCHOOL | 4MULA VIEW UNIVERSITY FOURMULAE VULCAN SCHOOLING | FOURMULAE VULCAN SCHOOLING
和:
SELECT text
FROM test_data
WHERE replace_synonyms(
text,
word_synonyms_list(
word_synonyms( '4MULA', wordlist( 'formula', 'fourmula' ) ),
word_synonyms( 'VIEW', wordlist( 'vu' ) ),
word_synonyms( 'UNIVERSITY', wordlist( 'school' ) )
)
)
LIKE '%4MULA VIEW%%UNIVERSITY%'
输出:
| TEXT | | :----------------------- | | FORMULA VIEW UNIVERSITY | | 4MULA VIEW UNIVERSITY | | FOURMULA VIEW UNIVERSITY | | FORMULA VU UNIVERSITY | | 4MULA VU UNIVERSITY | | FOURMULA VU UNIVERSITY | | FOURMULA VU SCHOOL |
db<>fiddle here
Currently, in test_data table I'd have just a record such as
FORMULA VIEW UNIVERSITY
. In addition, I have a table for word substitution and synonyms in very similar fashion you included. Considering I have just the recordFORMULA VIEW UNIVERSITY
how could I invoke replace_synonyms such as:SELECT text FROM test_data WHERE replace_synonyms(...)) LIKE '%4MULA VU%%UNIVERSITY%'
. Notice that usually I will want to compare a new name which is not in test_data as the case of'%4MULA VU%%UNIVERSITY%'
交换它,以便同义词在 LIKE
过滤器中而不是在 table:
CREATE TABLE test_data ( text ) AS
SELECT 'FORMULA VIEW UNIVERSITY' FROM DUAL;
然后:
SELECT text
FROM test_data
WHERE text LIKE replace_synonyms(
'%4MULA VU%%SCHOOL%',
word_synonyms_list(
word_synonyms( 'FORMULA', wordlist( '4mula', 'fourmula' ) ),
word_synonyms( 'VIEW', wordlist( 'vu' ) ),
word_synonyms( 'UNIVERSITY', wordlist( 'school' ) )
)
)
输出:
| TEXT | | :---------------------- | | FORMULA VIEW UNIVERSITY |
db<>fiddle here