【问题标题】:String comparision in Oracle SQLOracle SQL 中的字符串比较
【发布时间】:2015-11-19 23:44:47
【问题描述】:
select * from employees
 where last_name between 'A' AND 'E';

为什么答案是'D'而不是'E',有没有其他方法可以获取详细信息

【问题讨论】:

  • 不完全是,A 和 E 之间的名称,但以字母开头
  • 字符串比较是在它们的 ASCII 值上完成的。因此,您将 last_name 的 ASCII 值与单个字符进行比较,这显然是不正确的。

标签: sql oracle oracle11g oracle10g string-comparison


【解决方案1】:
SELECT * FROM EMPLOYEES
WHERE Last_name Like 'A%'
OR Last_name Like 'E%';

这应该是答案....您编写的代码将准确显示 A 和 E 的名称....

【讨论】:

    【解决方案2】:

    'A' 和 'E' 之间的姓氏;

    字符串比较与比较数字不同。

    字符串比较是在它们的 ASCII 值上进行的。因此,您将 last_name 的 ASCII 值与 单个字符 进行比较,这不会给出您想要的输出。

    SQL> SELECT ename, ASCII(ename), ASCII('A'), ASCII('E') FROM emp;
    
    ENAME      ASCII(ENAME) ASCII('A') ASCII('E')
    ---------- ------------ ---------- ----------
    SMITH                83         65         69
    ALLEN                65         65         69
    WARD                 87         65         69
    JONES                74         65         69
    MARTIN               77         65         69
    BLAKE                66         65         69
    CLARK                67         65         69
    SCOTT                83         65         69
    KING                 75         65         69
    TURNER               84         65         69
    ADAMS                65         65         69
    JAMES                74         65         69
    FORD                 70         65         69
    MILLER               77         65         69
    
    14 rows selected.
    
    SQL>
    

    基于上述ASCII 值,您将只获得ename 的ASCII 值介于6569 之间的那些行。

    您需要先使用SUBSTR提取last_name的第一个字符,并与'A''E'进行比较。

    例如,我在 SCOTT 架构中使用标准的 emp 表,并添加两行以 'D''E' 开头的 ename。

    SQL> WITH DATA AS(
      2  SELECT ename FROM emp
      3  UNION
      4  SELECT 'DAWSON' FROM DUAL
      5  UNION
      6  SELECT 'EINSTEIN' FROM DUAL
      7  )
      8  SELECT * FROM DATA
      9  WHERE substr(ename,1,1) BETWEEN 'A' AND 'E';
    
    ENAME
    ----------
    ADAMS
    ALLEN
    BLAKE
    CLARK
    DAWSON
    EINSTEIN
    
    6 rows selected.
    

    【讨论】:

    • 比较多字符串和单字符串本身并没有错;请参阅我的第一个解决方案(速度更快,但与您的相同)。此外,字符串比较不是在 ASCII 值上进行,而是在排序规则上进行(当排序规则为 ascii_general_ci 时,这一致)。
    • @Amadan 我在哪里说将多字符串与单字符串进行比较是错误的?我说OP根据上下文做错了。是的,当您比较两个字符串时,它们会根据它们的 ASCII 值进行比较。
    • 抱歉,我好像弄错了。直接比较不使用排序规则。
    • @Amadan 没问题 :-)
    【解决方案3】:

    您的命令非常适合“姓名(不是开头)从 A 到 E 的员工”。 "E" 将加入。"Einstein" 退出,因为它比"E"

    WHERE last_name >= 'A' AND last_name < 'F'
    

    会给你你想要的。

    或者,你可以这样做

    WHERE SUBSTR(last_name, 1, 1) BETWEEN 'A' AND 'E'
    

    但它会很慢,因为它无法使用索引。

    【讨论】:

    • 谢谢你的回答,但我的问题是为什么它不给到 E,假设如果我给的工资在 2000 到 5000 之间,它会一直到 5000,那么为什么不能取名字,什么是字符串方法
    • 直到 E。你只是没有任何被称为 "E" 的员工。你想问的问题是“为什么不给名字以 E 开头的员工”,我也解释了。
    • 为了背负你的例子,如果你做BETWEEN 2000 AND 5000,你会期望它给你5000.85吗?同理,"Einstein" 不是BETWEEN 'A' AND 'E'
    • 请再读一遍。你的命令现在相当于BETWEEN 'A' AND 'F'。如果你看我的问题,我说的是&lt; 'F',而不是&lt;= 'F'。你的命令给你"F"如果它在你的表中(因为'F' &lt;= 'F'),但不是"Franklin",因为"Franklin"不是 &lt;= 'F'。打开字典,看看单词的顺序; "E" 在每个以"E" 开头的单词之前,"F" 在每个以"F" 开头的单词之前。但是每个以"E" 开头的单词都是&lt; 'F'
    • 谢谢@Amadan,我没有看到你的第二条评论,我明白了,还有'A'和'E'之间的substr(last_name,1,1);
    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 2011-11-09
    • 2010-09-28
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多