如果有人提出这个问题,我很抱歉,我无法用语言表达。
我被要求过滤出查询中的行,其中来自一个字段的文本包含在另一个字段中。一个例子可能会更好地解释它:
Column_1 Column_2
Low Static Static
Static Static
Static Clear
Static
Very Low Freq Freq
查询的结果应该只返回第3行和第4行,因为第1,2和5行包含相似的字符串。现在,我有以下条件:
WHERE
((Column_2 NOT LIKE '%' || Column_1 || '%')
OR (Column_1 NOT LIKE '%' || Column_2 || '%' OR Column_1 IS NULL))
然而,当我只想返回第3行和第4行时,它返回第1,3,4和5行。这只是示例数据,我的实际数据集在第1列和第2列包含许多不同的文本字符串,所以我可以只是编写特定的case语句来驱逐列相似的某些实例。
也许这是不可能的,因为我无法将字符串定义为2个空格中包含的内容,同时考虑到没有空格的情况?
由于
答案 0 :(得分:1)
对于您的表达,我认为您需要and
而不是or
:
WHERE ((Column_2 NOT LIKE '%' || Column_1 || '%') AND
(Column_1 NOT LIKE '%' || Column_2 || '%' OR Column_1 IS NULL)
)
你需要两个条件都是真的。您可能会发现逻辑更容易理解为:
WHERE NOT (Column_2 LIKE '%' || Column_1 || '%' OR
Column_1 LIKE '%' || Column_2 || '%'
)
答案 1 :(得分:0)
您要使用的方法是进行全表扫描,因此随着表的增长它不会扩展。如果要实现使用索引的更有效的解决方案(不使用Oracle大文本索引),请使用基于函数的索引预先计算列公共子串。
使用INSTR(),您可以查找列是否是另一列的子字符串,并返回该分数。 0表示不匹配。
create index ix_t_score on t (instr(nvl(column_1,' '), nvl(column_2, ' ')),
instr(nvl(column_2,' '), nvl(column_1, ' ')));
现在编写查询,以便Oracle允许Oracle使用索引。
-- Find rows that don't have common strings
select * from t
where instr(nvl(column_1, ' '), nvl(column_2, ' ')) = 0 and
instr(nvl(column_2, ' '), nvl(column_1, ' ')) = 0;
-- Find rows that do
select * from t
where instr(nvl(column_1, ' '), nvl(column_2, ' ')) > 0 or
instr(nvl(column_2, ' '), nvl(column_1, ' ')) > 0;
set autotrace on
Execution Plan
----------------------------------------------------------
Plan hash value: 4100696360
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 22 | | |
|* 2 | INDEX RANGE SCAN| IX_T_SCORE | 1 | 22 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(INSTR(NVL("COLUMN_1",' '),NVL("COLUMN_2",' '))=0 AND
INSTR(NVL("COLUMN_2",' '),NVL("COLUMN_1",' '))=0)
您可以通过创建确定性存储过程/函数来返回分数来简化它,并且SQL变得比上面简单得多。使用NVL()是为了处理带空值的列。