2

我需要在给定字符串的表中查询值。该表区分大小写,但我想在比较中执行 ToLower()。

假设我有一个包含以下数据的类表。

class    teacher
-----------------
Mat101   Smith
MAT101   Jones
mat101   Abram
ENG102   Smith

我的查询应该类似于

Select teacher From classes where lower(class) = 'math101'

这是进行比较的最佳方法吗?

更新

我无法控制数据库或数据。我是只读消费者。

4

6 回答 6

2

以下是有关基于函数的索引的更多信息(上面 Dave 所指的内容):

于 2008-12-23T17:56:18.430 回答
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,加布

于 2008-12-23T19:02:57.453 回答
1

由于您添加了您是数据库的只读用户,因此最好的方法接近您开始使用的方法:

Select teacher From classes where lower(class) = LOWER('math101')

请注意,我在输入参数中添加了 LOWER(),只是为了确保它也是小写的。有些人可能称之为“腰带和吊带”(又名redudant);我称之为良好的防御性编程。

于 2009-01-02T18:19:01.347 回答
0

您正在谈论的那种查询的缺点是它不能在类上使用索引(作为索引查找,也就是说 - 它仍然可以用于索引的快速完整扫描)。

但是,在现代版本的 Oracle 中,您可以在 LOWER(class) 上创建一个索引,然后该查询可以使用该索引。

于 2008-12-23T17:40:46.480 回答
0

不; 改进数据会更好:创建一个数字 ID 来表示这些看似无意义的类变体(可能还有一个关联的查找表来获取 ID)。在 where 子句中使用 ID 列,您应该会点击索引数字列。

如果这不是一个选项,请考虑在 lower(class) 上使用基于函数的索引。

如果这不是一个选项,并且“最佳”问题与性能严格相关,请考虑非规范化并添加一个包含 lower(class) 的列,可能填充有触发器。

如果这不是一个选项,请更新数据,使其全部为小写(并采取措施仅插入/更新小写类数据)。

如果你不能像那样更新数据,那么答案是“也许”。

在任何情况下,如果您没有测试列的索引,您就不能称之为最佳。

于 2008-12-23T18:15:06.973 回答
0

如果变体(Mat101、MAT101、mat101)引用相同的东西,它们应该具有相同的标识符。

根据数据量、更新频率、查询等,您可以考虑将数据复制到您通过复制中内置的清理/标准化阶段控制的数据库中。

当您说“我无法控制数据库”时,如果您可以查询,您将对数据库产生影响。有人控制了数据库,可能值得通过电子邮件/电话说,如果他们向该列添加 lower() 索引,那么它将减少您的查询对数据库的影响。

最后,如果变体足够简单,那么您可以尝试

Select teacher From classes where class in (lower('mat101'), upper('mat101'), initcap('mat1010')). 
于 2008-12-23T21:51:57.487 回答