【问题标题】:How to extract month number from date in OracleOracle如何从日期中提取月份数
【发布时间】:2019-08-29 10:33:55
【问题描述】:

我有ID_BB_SECURITY 列,其中日期值存储在此列中,例如'20190801'

我想从这个字段中获取月份数,例如八月的日期,我想得到 8。

我尝试了下面的查询,但它抛出了一个错误“文字不匹配”:

select to_number(to_date(ID_BB_SECURITY),'mm') from BT_EXPORT

我不确定是否必须忽略空值以避免错误

【问题讨论】:

  • (ID_BB_SECURITY / 100) % 100? % 应该是模数。如果它不起作用,请使用 MOD()。
  • 永远不要将 DATE 值存储在 VARCHAR 或 NUMBER 列中。使用 DATE 列
  • to_date(ID_BB_SECURITY) 将使用NLS_DATE_FORMAT 会话参数作为格式模型将字符串转换为日期;如果不匹配,那么您将收到错误消息(并且用户可以单独设置自己的会话参数,因此您永远不应该依赖默认值)。相反,您应该明确提供格式模型,例如:to_date(ID_BB_SECURITY, 'YYYYMMDD' )
  • 不明白谁以及为什么给我的帖子带来负面影响?是否有什么不可读或问题不清楚?
  • 我已经编辑了我的问题,因为我在不知道任何原因的情况下收到了负面反馈点

标签: sql oracle date select


【解决方案1】:

如果该值是数字或字符串,那么您可以将其转换为带有适当掩码的日期 - 这是您所缺少的,以及导致您收到错误的原因(因为它正在使用会话的 NLS_DATE_FORMAT 设置,这显然与数据的格式不匹配;但无论如何你都不应该依赖它,正如@MTO 在 cmets 中所说):

to_date(ID_BB_SECURITY, 'YYYYMMDD')

然后是extract the month number

select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT

或者你可以只使用一个子字符串:

select to_number(substr(ID_BB_SECURITY, 5, 2)) from BT_EXPORT;

那些假设一个固定的一致格式,当使用错误的数据类型时,这总是一个冒险的假设。 Ans 如果它是一个数字,他们正在执行从数字到字符串的隐式转换,为了更清晰,您可以将其转换为显式转换。

如果它已经是一个日期 - 当然应该是这样 - 那么你不需要转换:

select extract(month from ID_BB_SECURITY) from BT_EXPORT

【讨论】:

  • 您不需要提供格式模型;如果您不这样做,那么TO_DATE 将使用NLS_DATE_FORMAT 会话参数作为默认格式模型,如果这不匹配,那么您将收到相应的错误。但是,您应该提供一个明确的格式模型,因为每个用户都可以修改他们自己的会话参数(并且默认值在不同的国际地区可能不同),因此您不能依赖默认值在不同用户之间保持不变或一致。
  • @Alex Poole 我已经编辑了我的问题,因为我在不知道任何原因的情况下收到了负面反馈点
【解决方案2】:

如果你有一个数字,你可以用算术来提取月份:

select mod(floor(20190801 / 100), 100)
from dual;

【讨论】:

  • 赞成是唯一不依赖丑陋字符串操作的答案。
  • 一般工作,但它也适用于错误的数字,如 mod(floor(20191301 / 100), 100)mod(floor(20190230 / 100), 100) - 这取决于是否接受这些值的要求。
  • @TimBiegeleisen:被赞为唯一使用丑陋数字操作的答案。 :-)
【解决方案3】:

您可以尝试将数字日期转换为字符串,然后提取第 5 和第 6 个字符:

SELECT
    SUBSTR(TO_CHAR(ID_BB_SECURITY), 5, 2) AS mm
FROM BT_EXPORT;

但是,您最好使用适当的日期列。然后,您可以使用不那么苛刻的方法,例如:

SELECT
    TO_CHAR(ID_BB_SECURITY, 'mm') AS mm  -- assuming date
FROM BT_EXPORT;

【讨论】:

    【解决方案4】:
    select to_number(to_char(to_date('20190801', 'yyyymmdd'), 'mm')) from dual
    

    【讨论】:

      【解决方案5】:

      还有

      select extract(month from to_date('20190801', 'yyyymmdd')) from dual
      

      【讨论】:

        【解决方案6】:

        试试这个

        select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT
        

        这一个将数字转换为日期然后提取月份。

        【讨论】:

          【解决方案7】:

          您的日期列的值以以下格式“yyyymmdd”存储,其中

          • yyyy 是年份
          • mm 月份
          • 日期 所以为了返回月份的数值(mm)我们可以这样做:

            1:首先将值从数字转换为日期使用 to_date(20190801,'yyyymmdd')

            2: 使用 to_date 运算符获取月份 to_char(to_date(20190801,'yyyymmdd'),'mm')

          【讨论】:

            猜你喜欢
            • 2018-02-16
            • 2019-03-20
            • 1970-01-01
            • 1970-01-01
            • 2014-05-01
            • 2019-08-31
            • 2017-06-14
            • 2021-04-02
            • 2016-08-20
            相关资源
            最近更新 更多