使用SQL将度/分/秒转换为小数

使用SQL将度/分/秒转换为小数,sql,Sql,是否存在将度/分/秒(保存在A列)转换为小数(保存在新的B列)的SQL脚本?我在谷歌上搜索了现有的解决方案,但所有的例子都提到小数->度/分/秒。我很欣赏任何例子,因为我不擅长SQL脚本编写。以下几点似乎有效: SELECT DMS, DEGREES + (MINUTES / 60) + (SECONDS / (60 * 60)) AS DECIMAL_DEGREES FROM (SELECT DMS, TRUNC(DMS) AS DEGREES,

是否存在将度/分/秒(保存在A列)转换为小数(保存在新的B列)的SQL脚本?我在谷歌上搜索了现有的解决方案,但所有的例子都提到小数->度/分/秒。我很欣赏任何例子,因为我不擅长SQL脚本编写。

以下几点似乎有效:

SELECT DMS, DEGREES + (MINUTES / 60) + (SECONDS / (60 * 60)) AS DECIMAL_DEGREES
  FROM (SELECT DMS,
               TRUNC(DMS) AS DEGREES,
               TRUNC((DMS - TRUNC(DMS)) * 100) AS MINUTES,
               ((DMS * 100) - TRUNC(DMS * 100)) * 100 AS SECONDS
          FROM TEST_DMS)
或者,如果您更喜欢将其作为一个表达:

SELECT DMS,
       TRUNC(DMS) +
         (TRUNC((DMS - TRUNC(DMS)) * 100) / 60) +
         (((DMS * 100) - TRUNC(DMS * 100)) * 100) / (60 * 60) AS DECIMAL_DEGREES
  FROM TEST_DMS
至少这些结果与我信任、生锈的HP-41C返回的结果一致。:-)


分享和享受。

我参与了一个项目……我使用脚本解决了oracle db上DMS转换的问题

SELECT 
CASE
WHEN LENGTH(longitude)=7 THEN ROUND (cast(substr(longitude, 1, 1) as numeric(10,5)) +  cast(substr(longitude, 3, 2) as numeric(10,5))/60 +  cast(substr(longitude, 6, 2) as numeric(10,5))/3600,4) 
WHEN LENGTH(longitude)=8  THEN ROUND (cast(substr(longitude, 1, 2) as numeric(10,5)) +  cast(substr(longitude, 4, 2) as numeric(10,5))/60 +  cast(substr(longitude, 7, 2) as numeric(10,5))/3600,4)
ELSE
ROUND (CAST (longitude as Numeric(10,5)),4)
END AS LONGITUDE,
CASE
WHEN LENGTH(latitude)=7 THEN ROUND (cast(substr(latitude, 1, 1) as numeric(10,5)) +  cast(substr(latitude, 3, 2) as numeric(10,5))/60 +  cast(substr(latitude, 6, 2) as numeric(10,5))/3600,4) 
WHEN LENGTH(latitude)=8  THEN ROUND (cast(substr(latitude, 1, 2) as numeric(10,5)) +  cast(substr(latitude, 4, 2) as numeric(10,5))/60 +  cast(substr(latitude, 7, 2) as numeric(10,5))/3600,4)
ELSE
ROUND (CAST (latitude as Numeric(10,5)),4)
END AS LATITUDE

我用下面的方法做同样的事情

declare @cord  varchar (max)

set  @cord=  '2504N 05534E'

select

case when  CHARINDEX(' ', @cord,1)>0 then
case when  right(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', @cord,1)-1))),1) = 'N' then
(left(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', @cord,1)-1))),2))
+
(SUBSTRING(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', @cord,1)-1))),3,2)/60.0)
else
-1*(
(left(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', @cord,1)-1))),2))
+
(SUBSTRING(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', @cord,1)-1))),3,2)/60.0)
)
end
end latitude
,case when  CHARINDEX(' ', @cord,1)>0 then
 case when right(LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', @cord,1),100))),1) = 'E' then
(left(LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', @cord,1),100))),3) )
+
(SUBSTRING( LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', @cord,1),100))),4 
,2)/60.0)
else
-1*(
(left(LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', @cord,1),100))),3) )
+
(SUBSTRING( LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', @cord,1),100))),4 
,2)/60.0)
 )
 end
 end  longitude

,geography::Point(
     case when  CHARINDEX(' ', @cord,1)>0 then
        case when  right(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', 
 @cord,1)-1))),1) = 'N' then
        (left(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', @cord,1)-1))),2))
        +
        (SUBSTRING(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', 
 @cord,1)-1))),3,2)/60.0)
        else
        -1*(
        (left(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', @cord,1)-1))),2))
        +
        (SUBSTRING(LTrIM(RTRIM(left( @cord, CHARINDEX(' ', 
 @cord,1)-1))),3,2)/60.0)
        )
        end
     end 
     ,case when  CHARINDEX(' ', @cord,1)>0 then
        case when right(LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', 
 @cord,1),100))),1) = 'E' then
        (left(LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', 
 @cord,1),100))),3) )
        +
        (SUBSTRING( LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', 
 @cord,1),100))),4 ,2)/60.0)
        else
        -1*(
        (left(LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', 
 @cord,1),100))),3) )
        +
        (SUBSTRING( LTrIM(RTRIM(SUBSTRING( @cord, CHARINDEX(' ', 
 @cord,1),100))),4 ,2)/60.0)
        )
        end
    end  
    , 4326)  
      as geography_Point    

根据@user2621989,这里的答案是他的查询的SQL Server版本:

DECLARE @longitude varchar(max) = '50°03''10"'
DECLARE @latitude varchar(max) = '15°00''50"'

SELECT 
CASE
WHEN LEN(@longitude)=8 THEN ROUND (cast(SUBSTRING(@longitude, 1, 1) as numeric(9,6)) +  cast(SUBSTRING(@longitude, 3, 2) as numeric(9,6))/60 +  cast(SUBSTRING(@longitude, 6, 2) as numeric(9,6))/3600,4) 
WHEN LEN(@longitude)=9  THEN ROUND (cast(SUBSTRING(@longitude, 1, 2) as numeric(9,6)) +  cast(SUBSTRING(@longitude, 4, 2) as numeric(9,6))/60 +  cast(SUBSTRING(@longitude, 7, 2) as numeric(9,6))/3600,4)
ELSE
ROUND (CAST (@longitude as numeric(9,6)),4)
END AS longitude,
CASE
WHEN LEN(@latitude)=8 THEN ROUND (cast(SUBSTRING(@latitude, 1, 1) as numeric(9,6)) +  cast(SUBSTRING(@latitude, 3, 2) as numeric(9,6))/60 +  cast(SUBSTRING(@latitude, 6, 2) as numeric(9,6))/3600,4) 
WHEN LEN(@latitude)=9  THEN ROUND (cast(SUBSTRING(@latitude, 1, 2) as numeric(9,6)) +  cast(SUBSTRING(@latitude, 4, 2) as numeric(9,6))/60 +  cast(SUBSTRING(@latitude, 7, 2) as numeric(9,6))/3600,4)
ELSE
ROUND (CAST (@latitude as numeric(9,6)),4)
END AS latitude
返回

longitude       latitude
50.05280000000  15.01390000000

等等,这三个值是如何保存在一列中的?这可能首先是一个数学问题,而不是SQL问题。@X-Zero:不幸的是,它们保存在一列中,例如41.182973。如果度数、分和秒分别保存在不同的列中,那么我可以简单地将分除以60,秒除以3600。41.182973度/分/秒是多少?“这就是我所期望的十进制数。”斯塔克同意,似乎是小数。特别是因为一分钟只有60秒(不是73秒)…@stark:不,它最初写为4118'29.73秒。然后将其合并到SQL表中的单个列中。所以,这似乎令人困惑,但它是deg/min/sec。