admin

Oracle SQL:从日期中提取一年中的星期将得出随机结果

sql

我一直在使用以下语句从日期中获取一年中的第几周:

TO_CHAR(TO_DATE(tbl.col,'YYYY/MM/DD'),'IW') AS week

现在我收到奇怪的结果,我似乎无法弄清楚。对于以下日期,我将收到第24周的信息:

17年6月19日|| 17年6月23日|| 2015年6月24日|| 2015年6月25日|| 17年6月29日|| 17年6月30日

为此,我收到25:

17年6月20日|| 17年6月21日|| 17年6月22日|| 17年6月26日|| 17年6月27日|| 17年6月28日

…而且这种情况还在继续。现在我所有的查询都显示不正确的数据,我有点担心。我直到现在才注意到的唯一原因是因为第26、27、30、31和32周没有结果,而我的其他任何查询都不是这种情况。

任何建议或指向可能的错误的指针,不胜感激。

谢谢!


阅读 163

收藏
2021-07-01

共1个答案

admin

[TL; DR] 只需使用:TO_CHAR( tbl.col, 'IW' )

您有多个问题:

  1. 数据类型为“日期”

您调用TO_DATE( string, format_model )DATE(不是VARCHAR2),这将导致甲骨文做的隐式转换DATEVARCHAR2使用NLS_DATE_FORMAT会话参数作为格式的模型,所以您可以将其转换回DATE。因此,您实际上在做:

    TO_CHAR(
  TO_DATE(
    TO_CHAR(
      tbl.col,
      ( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
    ),
    'YYYY/MM/DD'
  ),
  'IW'
)

不要这样做 ,只需使用:

    TO_CHAR( tbl.col, 'IW' )

如果这样做,则以下问题无关紧要。

  1. 正如RealCheeseLord指出的那样,格式模型中的年和日的位置是相反的。和
  2. 您正在使用YYYY年格式模型,因此所有年份都将出现在公元1世纪。

范例

    SELECT TO_CHAR( TO_DATE( '19-Jun-17', 'YYYY/MM/DD' ), 'YYYY-MM-DD' ) AS dt
FROM   DUAL

输出

    DT
----------
0019-06-17

如果您不打算修复隐式字符串转换,那么您可能会想要:

    TO_CHAR(TO_DATE(tbl.col,'DD-MON-YY'),'IW') AS week

或(取决于您希望99年是1999年还是2099年):

    TO_CHAR(TO_DATE(tbl.col,'DD-MON-RR'),'IW') AS week
  1. 您正在将MM格式模型用于MON格式化的数据-这不一定是MM匹配MON``MONTH的问题但您可能应该使用正确的模型。
2021-07-01