MySql如何将varchar(纬度,经度)转换为十进制字段?

时间:2013-09-09 19:03:08

标签: mysql google-maps decimal latitude-longitude varchar

在mysql中,我有一个包含谷歌地图提供的纬度和经度的varchar。 我需要能够基于边界框值进行查询,但不需要现在可用的地理要素。我正在尝试使用varchar中找到的Decimal值填充2个新的Decimal字段。这是我正在尝试使用的查询,但结果是新字段中的所有舍入值。

示例数据:

'45.390746926938185, -122.75535710155964',
'45.416444621636415, -122.63058006763458'

创建表:

CREATE TABLE IF NOT EXISTS `cameras` (
  `id` int(11) NOT NULL auto_increment,
  `user_id` int(75) NOT NULL,
  `position` varchar(75) NOT NULL,
  `latitude` decimal(17,15) default NULL,
  `longitude` decimal(18,15) default NULL,
  `address` varchar(75) NOT NULL,<br />
  `date` varchar(11) NOT NULL,<br />
  `status` int(1) NOT NULL default '1',
  `duplicate_report` int(11) NOT NULL default '0',
  `missing_report` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `user_id` (`user_id`),
  KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1050 ;

SQL:

UPDATE cameras
SET latitude = CAST( (substring(position,1,locate(',',position))) AS DECIMAL(17,15) ),
    longitude = CAST( (substring(position,locate(',',position)+1)) AS DECIMAL(18,15) )

SQL替代尝试:

UPDATE cameras
SET latitude = CONVERT( (substring(position,1,locate(',',position))), DECIMAL(17,15) ),
    longitude = CONVERT( (substring(position,locate(', ',position)+1)), DECIMAL(18,15) )

结果字段值适用于两种情况:

45.000000000000000 and -122.000000000000000
AND
45.000000000000000 and -122.000000000000000

谁能看到我做错了什么? 感谢。

1 个答案:

答案 0 :(得分:2)

CAST和CONVERT表单似乎都是正确的。

SELECT CAST((SUBSTRING(t.position,1,LOCATE(',',t.position))) AS DECIMAL(17,15)) AS lat_
     , CONVERT(SUBSTRING(t.position,LOCATE(', ',t.position)+1),DECIMAL(18,15)) AS long_
  FROM (SELECT '45.390746926938185, -122.75535710155964' AS `position`) t

              lat_                   long_
------------------  ----------------------
45.390746926938185    -122.755357101559640

我认为立场是一个保留词,但在这种情况下我认为不重要。但是,分配表别名并限定所有列引用

并不会有什么坏处
UPDATE cameras c
   SET c.latitude = CAST((SUBSTRING(c.position,1,LOCATE(',',c.position))) AS DECIMAL(17,15))
     , c.longitude = CAST((SUBSTRING(c.position,LOCATE(',',c.position)+1)) AS DECIMAL(18,15))

但我怀疑这不会解决问题。

要检查的一件事是在表上定义的更新触发器之前或之后,是否舍入/修改分配给纬度和经度列的值?

我建议您尝试运行一个查询。

SELECT CAST((SUBSTRING(c.position,1,LOCATE(',',c.position))) AS DECIMAL(17,15)) AS lat_
     , CAST((SUBSTRING(c.position,LOCATE(',',c.position)+1)) AS DECIMAL(18,15)) AS lon_
  FROM cameras c

并验证是否产生了您期望的十进制值。

点字符应该被识别为小数点。 position列是否包含一些其他特殊字符,如空格或其他内容?

根据您发布的内容,看起来CAST和CONVERT在整数部分上工作,直到小数点。 (那里不应该有隐式转换为有符号整数,因此不清楚为什么不包括小数点后面的字符。)


如果你能找出用于表示小数点的字符,那么你可以使用MySQL REPLACE()函数来替换那些带有简单点字符的字符。