【问题标题】:SQL Where Clauuse Date - Not A Valid Month ErrorSQL Where 子句日期 - 不是有效的月份错误
【发布时间】:2017-04-19 17:34:41
【问题描述】:

我正在尝试在 SQL Developer(使用 Oracle 数据库)中运行此 sql 查询。基本上,我想选择 A.APPT_DATE 至少 2 个月大的所有列,但我不断收到“无效月份错误” - 以粗体突出显示这一点。如果我把这个 where 子句去掉,它就可以正常工作。

SELECT D.DOC_ID AS "Doctor ID", D.STATUS, A.APPT_DATE, COUNT(DISTINCT A.APPT_ID) AS "Number of appointments", DI.CASE, P.PET_ID AS "Pet ID", P.PET_NAME AS "Pet Name"
FROM VET_DOCTOR D
JOIN 
APPOINTMENT A ON (D.DOC_ID=A.DOC_ID) WHERE A.APPT_DATE <= DATE '10-January-2016'
JOIN 
DIAGNOSIS DI ON (A.APPT_ID=DI.APPT_ID) 
JOIN
PET P ON (A.PET_ID=P.PET_ID) WHERE DI.CASE IN('Socialisation','Dental') 
GROUP BY D.DOC_ID, D.STATUS, A.APPT_DATE, A.APPT_ID, DI.CASE, P.PET_ID, P.PET_NAME;

【问题讨论】:

  • 尝试将日期设为“2016 年 1 月 10 日”(不带 -)
  • 哪个数据库?
  • @kevchadders 我试过并得到以下错误: 原因:输入中的文字必须与格式字符串中的文字长度相同(前导空格除外)。如果启用了“FX”修饰符,则文字必须完全匹配,没有多余的空格。
  • 我假设你的代码中的那些**是错误的。附言。从您的错误消息中,它的 Oracle 作为您的数据库
  • 如果表格中的日期格式不同,那么您应该使用不同的格式。

标签: sql database oracle date where-clause


【解决方案1】:

我不确定,但我猜日期格式类似于DD-Mon-YYYY。所以你需要这样做:'10-JAN-2016'

如果有帮助,请告诉我。

【讨论】:

  • 日期格式为 DD-MM-YYYY,日期输入为 '01-January-1999' 例如。我刚刚尝试了您的建议,但它仍然给了我“不是有效月份”的错误。谢谢
  • 那么根据你的日期格式DD-MM-YYYY你应该使用'10-01-2016'吧?
【解决方案2】:

假设您的日期存储在正确的数据类型 DATE

你能试试 YYYY-MM-DD 格式吗?我希望它可以使用 Datetime Literals

<= DATE '2016-01-10'

【讨论】:

  • 谢谢我尝试了你的建议,但收到以下错误:SQL 命令未正确结束"
  • 您能否暂时简化查询,以防错误出现在 SQL 的另一部分。所以尝试类似:SELECT * FROM APPOINTMENT WHERE APPT_DATE
  • 或使用其他日期格式建议。这将帮助您专注于日期问题
【解决方案3】:

试试这个:

 WHERE A.APPT_DATE <= TO_DATE('10/JAN/2016','dd/mon/yyyy')

【讨论】:

    【解决方案4】:
    to_DATE('10-01-2016','DD-MM-YYYY')
    

    所以你是独立于语言的

    【讨论】:

      【解决方案5】:

      两件事: 1. 如果要按标准方式输入,日期应输入为'DD-Mon-YYYY',例如'01-Jan-2016'。

      因此您的查询将是:

          SELECT D.DOC_ID AS "Doctor ID", D.STATUS, A.APPT_DATE, COUNT(DISTINCT A.APPT_ID) AS "Number of appointments", DI.CASE, P.PET_ID AS "Pet ID", P.PET_NAME AS "Pet Name"
          FROM VET_DOCTOR D
          JOIN 
          APPOINTMENT A ON (D.DOC_ID=A.DOC_ID) WHERE A.APPT_DATE <= '10-Jan-2016'
          JOIN 
          DIAGNOSIS DI ON (A.APPT_ID=DI.APPT_ID) 
          JOIN
          PET P ON (A.PET_ID=P.PET_ID) WHERE DI.CASE IN('Socialisation','Dental') 
          GROUP BY D.DOC_ID, D.STATUS, A.APPT_DATE, A.APPT_ID, DI.CASE, P.PET_ID, P.PET_NAME;
      

      如果出现错误,试试这个:

      运行以下查询:

          ALTER SESSION SET nls_date_format = 'DD-Mon-YYYY';
      

      这将强制使用标准格式的日期输入。

      1. 如果您只想将其输入为整月,则:

        ALTER SESSION SET nls_date_format = 'DD-Month-YYYY';
        

      然后运行您的查询:

          SELECT D.DOC_ID AS "Doctor ID", D.STATUS, A.APPT_DATE, COUNT(DISTINCT A.APPT_ID) AS "Number of appointments", DI.CASE, P.PET_ID AS "Pet ID", P.PET_NAME AS "Pet Name"
          FROM VET_DOCTOR D
          JOIN 
          APPOINTMENT A ON (D.DOC_ID=A.DOC_ID) WHERE A.APPT_DATE <= '10-January-2016'
          JOIN 
          DIAGNOSIS DI ON (A.APPT_ID=DI.APPT_ID) 
          JOIN
          PET P ON (A.PET_ID=P.PET_ID) WHERE DI.CASE IN('Socialisation','Dental') 
          GROUP BY D.DOC_ID, D.STATUS, A.APPT_DATE, A.APPT_ID, DI.CASE, P.PET_ID, P.PET_NAME;
      

      此外,在您的原始查询中,我看到了一个 DATE,您是否尝试将您的日期“2016 年 1 月 10 日”转换为一个日期以进行比较?在这种情况下,您需要它类似于 TO_DATE('your date here', 'format string')。 为什么我问这个是因为,看看下面的两个查询,第一个抛出错误(和你得到的一样),第二个没有:

          SELECT sysdate FROM dual WHERE sysdate >= DATE '10-January-2016';
          SELECT sysdate FROM dual WHERE sysdate >= '10-January-2016';
      

      【讨论】:

      • 请参阅 docs.oracle.com/cd/B28359_01/server.111/b28286/… 以获取完整的日期格式列表。
      • 不要依赖NLS_DATE_FORMAT 来提供一致的日期格式 - 它是一个会话变量,每个用户都可以不同,每个用户都可以在会话中将其更改为他们想要的任何格式。如果你想要一个特定的日期格式掩码,那么specify it (with the NLS settings) in the TO_DATEfunction.
      • 同意。只是希望用户检查以解决实际问题。虽然我认为问题是在输入实际日期之前使用单词日期,但请参阅我在答案中的最后几行。
      【解决方案6】:

      这里的很多答案都非常正确地指出您需要使用 TO_DATE 函数将字符串转换为日期,并且您必须说明格式。但是,您的原始帖子说您要提取“至少两个月大”的实体。为此,我会使用:

      WHERE A.APPT_DATE <= ADD_MONTHS(sysdate,-2)
      

      那你明天就不需要重写查询了

      【讨论】:

        【解决方案7】:

        WHERE 子句不能位于JOIN 子句的中间:

        SELECT D.DOC_ID AS "Doctor ID",
               D.STATUS,
               A.APPT_DATE,
               COUNT(DISTINCT A.APPT_ID) AS "Number of appointments",
               DI.CASE,
               P.PET_ID AS "Pet ID",
               P.PET_NAME AS "Pet Name"
        FROM   VET_DOCTOR D
               JOIN APPOINTMENT A ON (D.DOC_ID=A.DOC_ID)
               JOIN DIAGNOSIS DI ON (A.APPT_ID=DI.APPT_ID) 
               JOIN PET P ON (A.PET_ID=P.PET_ID)
        WHERE  DI.CASE IN('Socialisation','Dental') 
        AND    A.APPT_DATE <= DATE '2016-01-10'
        GROUP BY D.DOC_ID, D.STATUS, A.APPT_DATE, A.APPT_ID, DI.CASE, P.PET_ID, P.PET_NAME;
        

        另外,如果您要使用日期文字,那么您需要使用格式DATE 'YYYY-MM-DD' 所以DATE '2016-01-10'

        但是,正如Christian Palmer 提到的,如果您想要至少两个月前的条目,那么您可以使用:

        AND A.APPT_DATE <= ADD_MONTHS( SYSDATE, -2 );
        

        【讨论】:

          【解决方案8】:

          这对我有用:

          cast (RN_EXECUTION_date as Date) >= '31-MAR-2018'
          

          RN_EXECUTION_Date 是日期时间戳格式。使用cast 函数,将其转换为日期格式(DD-MON-YEAR)

          【讨论】:

            猜你喜欢
            • 2021-04-05
            • 1970-01-01
            • 2015-03-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-05
            相关资源
            最近更新 更多