【问题标题】:MySql How to convert varchar (latitude, longitude) to Decimal fields?MySql如何将varchar(纬度,经度)转换为十进制字段?
【发布时间】:2013-09-09 19:03:07
【问题描述】:

在 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

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

【问题讨论】:

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


    【解决方案1】:

    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
    

    我认为 position 是一个保留字,但在这种情况下我认为这并不重要。但是分配一个表别名并限定所有列引用并没有什么坏处

    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
    

    并验证生成您期望的十进制值。

    点字符应被识别为小数点。位置列是否包含其他一些特殊字符,例如空格或其他什么?

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


    如果您能弄清楚用什么字符来表示小数点,那么您可以使用 MySQL REPLACE() 函数将这些字符替换为简单的点字符。

    【讨论】:

    • 感谢您的帮助,但运行最后一个查询导致所有值都具有 .000000000000000,我认为 .导致问题。
    • @user1598994:尝试像我的答案顶部那样的查询,您可以在其中输入点。这行得通吗?
    • 对不起 spencer7593,第一次查询的结果还是一堆零
    • @user1598994。这真的很奇怪。想到的是一个字符,而不是点被用作小数点。这通常是一个区域设置,但我认为 MySQL 不允许您更改小数点字符。我认为这不会是由字符集设置引起的。 你运行的是什么版本的 MySQL? show variables like 'version';你在“mysql”命令行客户端测试过吗?当我运行第一个查询时,我得到了我期望的十进制值。奇数。
    • 我们使用的是 5.0.18-nt
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 2013-01-05
    • 1970-01-01
    相关资源
    最近更新 更多