Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在Oracle中比较日期?_Sql_Oracle_Date Arithmetic - Fatal编程技术网

Sql 如何在Oracle中比较日期?

Sql 如何在Oracle中比较日期?,sql,oracle,date-arithmetic,Sql,Oracle,Date Arithmetic,我认为这是一个简单的问题,但谷歌并没有帮上很大的忙。也许我不擅长我正在寻找的东西 SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE FROM ORDERS WHERE FORMAT(ORDER_DATE, 'DD-MMM-YYYY') = '07-JUN-2000'; 它告诉我我使用的标识符无效。我试过使用MON而不是MMM,但这也没用 不确定它是否有任何区别,但我使用的是Oracle SQL Developer。我不认为格式是Oracle函数 我想你的

我认为这是一个简单的问题,但谷歌并没有帮上很大的忙。也许我不擅长我正在寻找的东西

SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE
FROM ORDERS
WHERE FORMAT(ORDER_DATE, 'DD-MMM-YYYY') = '07-JUN-2000';
它告诉我我使用的标识符无效。我试过使用
MON
而不是
MMM
,但这也没用


不确定它是否有任何区别,但我使用的是Oracle SQL Developer。

我不认为
格式
是Oracle函数

我想你的意思是
到\u CHAR

SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE
FROM ORDERS
WHERE TO_CHAR(ORDER_DATE, 'DD-MMM-YYYY') = '07-JUN-2000';

尝试
到字符(订单日期,'DD-MON-YYYY')

与您的日期使用相关的多个问题:

其中格式(订单日期,'DD-MMM-YYYY')='07-JUN-2000'

  • 格式不是Oracle支持的内置函数
  • 永远不要将字符串日期进行比较。不过,您可能很幸运,您强制Oracle根据您的特定于语言环境的NLS设置执行隐式数据类型转换。你必须避免它。始终使用TO_DATE将字符串显式转换为日期
  • 记住

    To display                      : Use TO_CHAR
    Any date arithmetic/comparison  : Use TO_DATE
    
    性能瓶颈:

    假设在日期列上有一个常规的B树索引。现在,下面的过滤器谓词将永远不会使用索引,因为它是to_CHAR函数:

    WHERE TO_CHAR(ORDER_DATE, 'DD-MM-YYYY') = '07-06-2000';
    
    因此,在上述查询中使用TO_CHAR完全没有意义,因为它不比较日期,也不能提供良好的性能

    正确的方法:

    进行日期比较的正确方法是:

    WHERE ORDER_DATE = TO_DATE('07-JUN-2000','DD-MON-YYYY','NLS_DATE_LANGUAGE=ENGLISH');
    
    它将使用ORDER_DATE列上的索引,因此在性能方面会更好。此外,它还比较日期而不是字符串

    正如我已经说过的,当您的日期中没有时间元素时,您可以使用ANSI date literal,它是NLS独立的,也不需要编写代码

    WHERE ORDER_DATE = DATE '2000-06-07';
    
    它使用固定格式'YYYY-MM-DD'

    尝试以下操作:

    SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE
    FROM ORDERS
    WHERE trunc(to_date(ORDER_DATE, 'DD-MMM-YYYY')) = trunc(to_date('07-JUN-2000'));
    


    为什么要将日期转换为字符串来进行比较?为什么不在订单日期为'2000-06-07'的地方执行
    ?订单日期的数据类型是什么?如果是日期,则需要
    其中订单日期=截止日期('07/06/2000','dd/mm/yyyy')
    。这假设order_date列中没有存储时间元素(即存储的所有内容都在午夜)。您在Oracle手册中的何处找到了
    format()
    函数?为什么您接受了完全错误的答案?@Siyual
    '2000-06-07'
    是字符串,而不是日期。您的LHS是正确的,但是,您必须在RHSW上使用TO_DATE或ANSI DATE Literal转换右侧是否更好?(如果订单日期被编入索引…)一个更大的问题是,为什么要这么做?为什么不与标准日期格式进行比较呢?正如Siyual已经建议的那样。是的,比我建议的要好。老实说,我一直都是这样做的,所以我知道我可以直接比较日期字段。我猜很多人最终可能更喜欢转换成char,因为他们不知道数据库以何种格式存储数据,也不想费心去弄清楚(似乎我属于这样的群体:-)这是完全错误的,应该始终避免。永远不要将字符串与日期进行比较。始终使用TO_DATE或ANSI DATE Literal将字符串显式转换为日期。@Veverke首先,ANSI DATE Literal是NLS独立的,而且它没有时间部分。第二,TO_DATE倾向于NLS设置,我已经提到了这一点。你确定你建议的是Oracle而不是SQL Server上的内容吗?更好的方法是在参数中使用
    to_date
    ,而不是在列中使用
    to_char
    。最好使用
    to_char(订单日期,'DD-MM-YYYY')='07-06-2000'
    为了独立于会话
    NLS\u DATE\u LANGUAGE
    @Wernfried,我真的很想看看证据。我从未在现实世界中听说过这种做法。@LalitKumarB,Wernfried,OP比较RHS中sring格式的日期,并询问为什么它抛出无效标识符。我觉得我的回答澄清了问题question@Lalit库马尔B:比较包含日期部分的字符串没有什么错。它通常非常可读(例如,
    to_char(mydate,'yyyyymm')='201510'
    )。不过,Wernfried的评论很重要:在处理月份名称时,应该指定日期语言。所以这是对这个问题的正确答案,只是它本可以更好:——)@Wernfried你在哪里看到OP讲述了关于时间部分的事情?“ANSI日期文字不支持任何时间分数值,只支持日期。您在哪里看到我的答案没有关注ANSI日期文字的用法?我已经清楚地提到“当您只处理日期而不处理时间部分时,最好使用ANSI日期文字。”。“@Wernfried似乎你没有正确阅读我的答案。我在第3点中明确提到,“当只处理日期而不处理时间部分时,最好使用ANSI日期文字。”。那么,这有什么错呢?我愿意接受你的评论:-)是的,我错过了,对不起。但是,
    其中订单日期=截止日期('07-JUN-2000','DD-MON-YYYY')
    依赖于会话
    NLS\u日期语言
    @Wernfried没有问题。NLS与TO_DATE的依赖关系是另一回事。ANSI日期文字是完全独立于NLS的,因为它遵循标准格式。无论如何,我将编辑我的答案以添加到日期的NLS依赖项。它与数据类型无关,但与值有关。列上的常规索引将在索引结构中存储列值,而在列上应用函数不会命中常规索引,因为我们不再寻找这些索引值。此外,
    其中订单日期=截止日期('07-JUN-2000','DD-MON-YYYY','NLS\U日期语言=英语')将使用订单日期列上的常规索引。因此,在性能方面也要好得多
    
    WHERE ORDER_DATE = TO_DATE('07-JUN-2000','DD-MON-YYYY','NLS_DATE_LANGUAGE=ENGLISH');
    
    WHERE ORDER_DATE = DATE '2000-06-07';
    
    SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE
    FROM ORDERS
    WHERE trunc(to_date(ORDER_DATE, 'DD-MMM-YYYY')) = trunc(to_date('07-JUN-2000'));