MySql How to convert varchar (latitude, longitude)

2019-07-21 05:04发布

In mysql I have a varchar containing latitude and longitude provided by Google maps. I need to be able to query based on a bounding box value, but have no need for the geo features now available. I'm trying to populate 2 new Decimal fields with the Decimal values found in the varchar. Here is the query that I'm trying to use, but the result are all rounded values in the new fields.

Sample data:

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

Create Table:

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 Alternate attempt:

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

The resulting field values are for both scenarios:

45.000000000000000 and -122.000000000000000
AND
45.000000000000000 and -122.000000000000000

Can anyone see what I'm doing wrong? Thanks.

1条回答
ゆ 、 Hurt°
2楼-- · 2019-07-21 05:45

Both the CAST and CONVERT forms seem to be correct.

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

I think position is a reserved word, but I don't think that matters in this case. But it wouldn't hurt to assign a table alias and qualify all column references

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))

But I suspect that won't resolve the problem.

One thing to check is for a before or after update trigger defined on the table, which is rounding/modifying the values assigned to the latitude and longitude columns?

I suggest you try running just a query.

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

and verify that produces the decimal values you expect.

A dot character should be recognized as a decimal point. Does the position column contain some other special characters, like a space or something?

From what you posted, it looks like the CAST and CONVERT working on the integer portion up to the decimal point. (There shouldn't be an implicit convert to signed integer in there, so it's not clear why the characters following the decimal point aren't being included.)


If you can figure out what character(s) are being used to represent the decimal point, then you could use a MySQL REPLACE() function to replace those with a simple dot character.

查看更多
登录 后发表回答