【问题标题】:Varchar m/d/yyyy to yyyy/mm/dd sqlvarchar m/d/yyyy 到 yyyy/mm/dd sql
【发布时间】:2015-11-10 14:36:30
【问题描述】:

我有一个文件以 m/d/yyyy 或 m/dd/yyyy 格式输入数据,具体取决于日期值是否为 2 位数字(例如 2015 年 4 月 1 日或 2015 年 4 月 14 日)。我需要将其转换为格式为 yyyy/mm/dd 的日期(例如 2015/04/01 或 2015/04/14)。我尝试了多种方法,但每次都收到错误“无效日期”。请帮忙。

我尝试过的事情:

cast((CASE WHEN CHAR_LENGTH(RSA_dt) <10 THEN 0 || TRIM(RSA_dt) end) AS DATE) 
CAST( CAST( RSA_dt AS DATE FORMAT 'DD-MMM-YY') AS DATE FORMAT 'YYYY-MM-DD')
cast(RSA_dt as date format 'YYYY-MM-DD')

【问题讨论】:

  • 你能告诉我们一些你尝试过的东西吗?这可能会让我们更容易回答为什么它不起作用。
  • @AdamV 我已经更新了我记得尝试过的那些。感谢您的帮助。
  • 您真的在使用 Teradata 吗?如果有,什么版本?
  • 我使用的是 Teradata v15

标签: sql date format teradata varchar


【解决方案1】:

您使用哪种工具进行加载? 加载此数据的最简单方法是在 TPT 作业中将该列定义为 VARDATE:

VARDATE(10) FORMATIN 'MM/DD/YY' FORMATOUT 'YYYY-MM-DD' 

否则,您会遇到问题,因为 Teradata 的 CAST 不喜欢单个数字的日/月。从 TD14 开始有 Oracle 的 TO_DATE,它仍然不喜欢个位数的月份,但至少可以容忍个位数的日期:

TO_DATE(CASE 
          WHEN RSA_dt LIKE '_/%' 
          THEN '0' || RSA_dt
          ELSE RSA_dt
        END
        ,'mm/dd/yyyy')

【讨论】:

    【解决方案2】:

    这适用于 TPT。

    Select '1/1/2014' as date1, 
    TO_DATE (
    case   
        when strtok(date1, '/', 1) between 1 and 9  and strtok(date1, '/', 2) between 1 and 9 then strtok(date1,'/', 3)||'/0'||strtok(date1, '/', 1)||'/0'||strtok(date1,'/', 2)
        when strtok(date1, '/', 1) between 1 and 9  and strtok(date1, '/', 2) > 9 then strtok(date1,'/', 3)||'/0'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
        when strtok(date1, '/', 1) > 9 and strtok(date1, '/', 2) between 1 and 9  then strtok(date1,'/', 3)||'/'||strtok(date1, '/', 1)||'/0'||strtok(date1,'/', 2)
        else  strtok(date1, '/', 3)||'/'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
    end , 'YYYY/MM/DD') as req_date
    

    【讨论】:

    • 欢迎来到 Stack Overflow!请不要只用源代码回答。尝试对您的解决方案如何工作提供一个很好的描述。请参阅:How do I write a good answer?。谢谢
    【解决方案3】:

    这是另一个解决方案。它使用正则表达式将前导零添加到任何一位数字,然后使用标准转换将其转换为使用现有格式的日期,然后再转换回标准格式。我举了几个例子:

    SELECT CAST(CAST(TD_SYSFNLIB.REGEXP_REPLACE('4/1/2015','(?<!\d)(\d)(?!\d)','0\1',1,0,'i') AS DATE FORMAT 'MM/DD/YYYY') AS DATE FORMAT 'YYYY-MM-DD');
    
    SELECT CAST(CAST(TD_SYSFNLIB.REGEXP_REPLACE('4/14/2015','(?<!\d)(\d)(?!\d)','0\1',1,0,'i') AS DATE FORMAT 'MM/DD/YYYY') AS DATE FORMAT 'YYYY-MM-DD');
    
    SELECT CAST(CAST(TD_SYSFNLIB.REGEXP_REPLACE('12/1/2015','(?<!\d)(\d)(?!\d)','0\1',1,0,'i') AS DATE FORMAT 'MM/DD/YYYY') AS DATE FORMAT 'YYYY-MM-DD');
    

    【讨论】:

    • 我有一个包含一位数月、日和小时的源(例如 20 年 4 月 3 日上午 6:16),并且这个正则表达式预先添加了我需要的所有三个前导零,以便使用Teradata 格式。
    【解决方案4】:

    您提供的格式似乎是您想要的,而不是您拥有的格式。试试这个:

    cast(RSA_dt as date format 'MM/DD/YYYY')
    

    【讨论】:

    • 当我使用它时,我仍然得到“为 RSA_dt 提供的日期无效”。
    【解决方案5】:

    如果您不使用 TPT,那么您将被困在玩一些糟糕的子字符串游戏。

    SELECT
     SUBSTR(chardate,INSTR(chardate,'/',1,2)+ 1,4) AS theYear,
    '00' || SUBSTR(chardate,1,INSTR(chardate,'1',1,1)-2) AS theMonth,
    '00' || SUBSTR(chardate,INSTR(chardate,'/',1,1)+ 1,INSTR(chardate,'/',1,2)  - INSTR(chardate,'/',1,1)-1) AS theDate,
    CAST (theYear || '-' || SUBSTRING(theMonth,LENGTH(theMonth) -1,2) || '-' || SUBSTR(theDate,LENGTH(thedate)-1,2) AS DATE) AS ItsADate
    
        FROM
        <yourtable>
    

    真的很丑,但应该可以。

    【讨论】:

    • 感谢 Andrew 的建议,但我收到错误“语法错误:单词 'chardate' 和 ',' 之间的预期内容”
    • 那个 SQL 对我来说很好用,我直接从 SQL 助手粘贴了它。
    • 您混合使用 SUBSTRINGSUBSTR 语法,而 ODBC 驱动程序修复了这个问题(Julie 可能会在失败的情况下使用 .NET)。将所有SUBSTRING 更改为SUBSTR
    • 哦,不错。我不得不承认,这不是我第一次这样做。 @Julie,现在试试,看看是否有效。
    • 解决了这个问题,但现在我收到错误“语法错误:数据类型“RSA_dt”与定义的类型名称不匹配”。 RSA_dt 在表中定义为 varchar(10)。想法?
    【解决方案6】:

    这应该可行。

    Select '1/2/2014' as date1,
    TO_CHAR(TO_DATE (
    case    
        when strtok(date1, '/', 2) between 1 and 9 then strtok(date1,'/', 3)||'/0'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
        else  strtok(date1, '/', 3)||'/'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
    end , 'YYYY/MM/DD'), 'YYYY/MM/DD') as "YYYY/MM/DD"
    

    【讨论】:

      【解决方案7】:

      这会起作用,虽然不是很漂亮。专门将 M/D/YYYY 转换为 YYYYMMDD

      select substr(YOURDATE,-4,4) || 
      substr('00'||SUBSTR(YOURDATE,1,to_number(regexp_instr(YOURDATE,'\/'))-1),-2,2) ||
      case when substr(YOURDATE,2,1) = '/' then
          case when substr(YOURDATE,4,1) = '/' then
              '0' || substr(YOURDATE,3,1)
          else substr(YOURDATE,3,2)
          end
      else case when substr(YOURDATE,5,1) = '/' then
              '0' || substr(YOURDATE,4,1)
          else substr(YOURDATE,4,2)
          end
      end as NEWDATE                                                                                              
      from YOURTABLE
      

      【讨论】:

        猜你喜欢
        • 2020-02-24
        • 1970-01-01
        • 2018-01-08
        • 2014-04-18
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 2014-04-30
        • 2013-10-19
        相关资源
        最近更新 更多