【问题标题】:Filtering a data set on dates with a weird format过滤具有奇怪格式的日期数据集
【发布时间】:2019-01-23 21:16:39
【问题描述】:

我有一列由以下格式的日期填充...

purch_dt
8/18/2014
9/27/2014
1/3/2015
10/29/2016
11/5/2016
2/9/2017
3/1/2017
6/29/2017
12/27/2017
2/25/2018

我想过滤数据集以仅包含特定范围内的日期,但是当我尝试在 WHERE purch_dt BETWEEN '3/1/2017' AND '6/29/2017' 之间进行编码时,我收到错误消息说“字符串转换为数值失败。”知道如何解决这个问题吗?

【问题讨论】:

标签: sql teradata


【解决方案1】:

不是 100% 确定这一点,但至少想提供帮助。我认为,如果您适当地转换该列,它应该可以工作,如下所示:

select *
  from my_table
  where cast(purch_dt as TIMESTAMP(0) format 'd/m/yyyy') 
          between date '2017-03-01' AND date '2017-06-29'

无论如何,我强烈建议将日期存储为DATE 而不是VARCHAR。将它们存储为VARCHAR 只是自找麻烦。

【讨论】:

  • 所以我将 where 子句更改为..... where cast(purch_dt as TIMESTAMP(0) format 'dd/mm/yyyy') between date '2017-03-01' AND date ' 2017-06-29' 并且有效
  • 当您在示例数据中显示的数天或数月有个位数时,这将不起作用。
【解决方案2】:

据我所知,Teradata 中没有任何格式或类型可以接受个位数的月份和日期。所以你必须解析这个丑陋的字符串并将其重建为日期。

STRTOK 将在 \ 分隔符上为您拆分,lpad 会在您需要它们的地方为您提供前导 0。

create volatile table vt_NotADate
(not_date varchar(10))
on commit preserve rows;

insert into vt_notadate values ('12/27/2017');
insert into vt_notadate values ('9/1/2017');


select
not_date,
cast(lpad(strtok(not_date,'/',1),2,'0') as char(2)) as m,
cast(lpad(strtok(not_date,'/',2),2,'0') as char(2)) as d,
strtok(not_date,'/',3) as y,
cast (y || '-' || m || '-' || d as date) as a_date
from
vt_notadate

【讨论】:

  • 解析更简单,正则表达式在单个数字前添加零:-) Cast(RegExp_Replace(str, '\b([0-9])\b', '0\1') AS DATE FORMAT 'mm/dd/yyyy')
  • Regex 几乎从来都不是我的首选...我试过这个:select Cast(RegExp_Replace('8/1/2018', '\b([0-9])\b', '0\1') AS DATE FORMAT 'mm/dd/yyyy'),得到一个无效的日期错误。
  • 您的 TD 版本是什么?至少从 15.10 开始,这应该可以工作,在出现一些差异之前......
  • 啊,这样就可以解释了。我们在这里慢慢地移动,我们仍然在 14.10。
猜你喜欢
  • 2018-11-17
  • 2017-10-23
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-21
  • 1970-01-01
相关资源
最近更新 更多