我有一个数据库表,用于存储从Web蜘蛛返回的数据。我有一个列包含varchar类型中不同事件的票价(因为scrapy蜘蛛必须在unicode中刮取数据)。我正在尝试返回列的最低价格,因为min()函数仅适用于INT类型的数据,我尝试使用this SO post的解决方案将列转换为整数:
ALTER TABLE vs_tickets ALTER COLUMN ticketprice TYPE integer USING (ticketprice::integer);
但我得到了错误:错误:整数的输入语法无效:
我也尝试过:change_column :vs_tickets, :ticketprice, 'integer USING CAST(ticketprice AS integer)'
但这也不起作用。
将列转换为INT类型的正确方法是什么?
答案 0 :(得分:3)
字符串中有小数位,因此简单的强制转换不起作用。你可以进行双重转换:
cast(cast(ticketprice as decimal(10, 2)) as int)
或:
(ticketprice::decimal(10, 2))::int
(parens并非绝对必要。)
编辑:
或者,正如Erwin指出的那样,只需使用numeric
:
(ticketprice::numeric)::int
Postgres比大多数其他数据库更加智能numeric
。 。 。毕竟,它支持非常大的数字;)
最终查询是:
ALTER TABLE vs_tickets
ALTER COLUMN ticketprice TYPE integer USING (ticketprice::numeric::integer);
答案 1 :(得分:2)
我打赌你的专栏有错误的字符。 您也可以使用float或numeric,因为如果转换为整数,您将丢失小数。
您需要创建一个函数来检查文本是否为数字,如isnumeric-with-postgresql
然后像这样检查每一行
select ticketprice
from vs_tickets
where ISNUMERIC(ticketprice) = false;
作为您的评论,您还应该尝试
SELECT ticketprice::float
答案 2 :(得分:1)
最好添加一个INT列,使用强制转换移动数据,然后删除旧的varchar列。
ALTER TABLE vs_tickets ADD COLUMN ticketprice_int TYPE int;
GO
update vs_tickets SET ticketprice_int = cast(ticketprice as int);
// if you fail to cast the varchar to int you can use Gordon's method
// update vs_tickets SET ticketprice_int = cast(cast(ticketprice as decimal(10, 2)) as int);
GO
ALTER TABLE vs_tickets DROP COLUMN ticketprice;
GO
ALTER TABLE vs_tickets RENAME COLUMN ticketprice_int to ticketprice;
GO
至少你可以判断演员/转换是否失败以及在哪里失败,并且能够在你不能回头之前检查并重新检查每一步。