我有一个数据库,我已经将2个日期列转换为varchar,目的是将1列子列入另一列。但是,现在我尝试使用时似乎无法转换数据类型:
ALTER TABLE datacomplete
ALTER COLUMN yearmonth TYPE DATE; /*Can't find a way to specify a format*/
它抛出了这个错误:
错误:列“yearmonth”无法自动转换为输入日期
提示:您可能需要指定“USING yearmonth :: date”。
我根本不确定如何使用该命令,是否有人可以提供帮助?
我的第一列格式为yyyy-mm-dd
,但我希望它只是yyyymm
,但我猜这一旦我将数据类型转换为日期后我就更容易了以某种方式切换格式。
第二列仅显示年份,因此我需要将其转换为格式为“yyyy
”的日期。
更新:第一个解决了,现在我需要将第二个转换为'yyyy'
ALTER TABLE pscomplete_1 ALTER COLUMN "year" TYPE DATE USING "year"::date;
它会抛出此错误
15:12:51 [ALTER - 0行,1.062秒] [代码:0,SQL状态:22007]错误:>类型日期的输入语法无效:“2016” ...执行1条语句,0行受影响,执行/获取时间:1.062 / 0.000秒> [0成功,1错误]
答案 0 :(得分:3)
USING关键字允许您将翻译功能提供给PostgreSQL。
对于您的第一列,您已经很容易拥有正确的DATE格式:
ALTER TABLE datacomplete ALTER COLUMN yearmonth TYPE DATE USING yearmonth::DATE;
对于你的第二栏,目前还不清楚PostgreSQL你想要的确切日期。假设我们想要给定年份的1月1日:
ALTER TABLE datacomplete ALTER COLUMN year TYPE DATE USING (year || '-01-01')::DATE;
答案 1 :(得分:0)
我知道你是从'YYYY-MM-DD'格式的VARCHAR列开始的。 所以我也会这样做。
你想要一个日期格式的列,你想要一个全数字格式的年份。
如果我没有被强制在全数字列中使用前导零,我更喜欢INT到字符串列。
如果我能做到这一点,我宁愿只做一次相同的推导。
这就是为什么我使用WITH子句(全局表表达式)将varchar转换为日期,然后我使用DATE_PART()函数的结果日期来创建yearmonth列。我经常看到日期算术更安全,并且通常比对日期文字进行细分更快(请记住,美国人的格式与欧洲人不同,欧洲内部和亚洲都有不同的格式,而不是像ISO一样日期格式)。所以我得出年份作为年份乘以100加上月份,并且当DATE_PART()返回一个浮点数时,我将整个表达式转换为INT。
所以这里是:
WITH foo(varchar_dt) AS (
SELECT '2017-01-11'
UNION ALL SELECT '2016-12-11'
UNION ALL SELECT '2016-11-11'
UNION ALL SELECT '2016-10-11'
)
, foo_with_date AS (
SELECT
varchar_dt
, CAST(varchar_dt AS DATE) AS the_date
FROM foo
)
SELECT
varchar_dt
, the_date
, CAST(DATE_PART('year',the_date)*100 + DATE_PART('month',the_date) AS INT) AS yearmonth
FROM foo_with_date
;
varchar_dt|the_date |yearmonth
2017-01-11|2017-01-11| 201,701
2016-12-11|2016-12-11| 201,612
2016-11-11|2016-11-11| 201,611
2016-10-11|2016-10-11| 201,610
我无法自拔 - 我觉得这个更清洁了,按年来过滤会变成一个整数过滤,整数至少比字符串快一点。
快乐的玩耍
Marco the Sane