我需要在表中查询给定字符串的值。该表区分大小写,但我想在比较中执行ToLower()。
假设我有一个包含以下数据的类表。
class teacher
-----------------
Mat101 Smith
MAT101 Jones
mat101 Abram
ENG102 Smith
我的查询应该是
Select teacher From classes where lower(class) = 'math101'
这是进行比较的最佳方式吗?
我无法控制数据库或数据。我是一位只读消费者。
答案 0 :(得分:2)
以下是有关基于函数的索引的更多信息(Dave在上面提到的内容):
答案 1 :(得分:2)
此方法要求您运行10gr2或更高版本。
在改变会话之前:
SQL> WITH LETTERS AS
2 (SELECT 'a' LETTER FROM DUAL UNION ALL
3 SELECT 'b' LETTER FROM DUAL UNION ALL
4 SELECT 'A' LETTER FROM DUAL UNION ALL
5 SELECT 'B' LETTER FROM DUAL)
6 SELECT LETTER FROM LETTERS
7 WHERE LETTER = 'A';
L
-
A
SQL>
如果您能够更改会话,则可以执行以下操作:
SQL> ALTER SESSION SET NLS_SORT=BINARY_CI;
Session altered.
SQL> ALTER SESSION SET NLS_COMP=LINGUISTIC;
Session altered.
SQL> WITH LETTERS AS
2 (SELECT 'a' LETTER FROM DUAL UNION ALL
3 SELECT 'b' LETTER FROM DUAL UNION ALL
4 SELECT 'A' LETTER FROM DUAL UNION ALL
5 SELECT 'B' LETTER FROM DUAL)
6 SELECT LETTER FROM LETTERS
7 WHERE LETTER = 'A';
L
-
a
A
如上所述更改会话会导致数据库对同一个字母的大写和小写版本进行排序和比较,并将其作为等效对象。有关详细信息,请参阅http://www.orafaq.com/node/91
HTH, 加布
答案 2 :(得分:0)
你所讨论的那种查询的缺点是它不能在类上使用索引(作为索引查找,即 - 它仍然可以用于索引的快速全扫描)。
在现代版本的Oracle中,您可以在LOWER(类)上创建一个索引,然后该查询可以使用该索引。
答案 3 :(得分:0)
没有;改进数据会更好:创建一个数字ID来表示这些看似毫无意义的类变体(可能还有一个相关的查找表来获取ID)。使用where子句中的ID列,您应该访问索引的数字列。
如果这不是一个选项,请考虑在lower(class)上使用基于函数的索引。
如果这不是一个选项,并且“最佳”的问题与性能严格相关,请考虑非规范化并添加包含较低(类)的列,可能填充了触发器。
如果这不是一个选项,请更新数据以使其全部小写(并采取措施仅插入/更新小写类数据)。
如果您无法更新这样的数据,那么答案就是“可能”。
在任何情况下,如果您尚未测试列的索引,则无法调用它。
答案 4 :(得分:0)
如果变体(Mat101,MAT101,mat101)引用相同的东西,它们应该具有相同的标识符。
根据数据量,更新频率,查询等,您可以考虑将数据复制到您使用复制中内置的清理/标准化阶段进行控制的数据库中。
当您说“我无法控制数据库”时,如果您可以查询,则会对数据库产生影响。有人控制了数据库,可能值得通过电子邮件/电话呼叫说,如果他们向该列添加了lower()索引,那么它将减少查询对数据库的影响。
最后,如果变体足够简单,那么你可以试试
Select teacher From classes where class in (lower('mat101'), upper('mat101'), initcap('mat1010')).
答案 5 :(得分:0)
由于您添加了自己是数据库的只读用户,因此最佳方法与您开始时的方法非常接近:
Select teacher From classes where lower(class) = LOWER('math101')
请注意,我在输入参数中添加了LOWER(),以确保它也是小写的。有些人可能会称之为“腰带和吊带”(又称还原剂);我称之为好防守编程。