1

原贴:Changing integer to floating point and adding decimal pointSQL使用Long/Latitude和Converting Int计算距离。为十进制

所以这里的背景故事:我与接收GPS从车辆坐标数据库工作,我需要弄清楚基础上的经度和纬度值这些车辆的行驶里程。但是,在数据库中,“经度/纬度”两列均为“Int/Not null”,并且没有小数位。因此,他们是这样的:

Latitude Longitude 
36158500 115949833 
36340000 115914667 
36153488 115944875 

,我需要它看起来像这样:

Latitude Longitude 
36.158500 115.949833 
36.340000 115.914667 
36.153488 115.944875 

与蒂姆莱纳的帮助下,我们找到了如何让小数点,但我不能使用我已经创建了公式来计算里程数。我必须能够根据radio_name搜索long/lat值,以便我可以单独查看每辆车的里程数,这就是为什么我创建了一个名为CTE和CTE2的临时表。但是,如果我调用临时表,代码将不起作用,因为它表示它是无效的对象。现在,如果我在下面的最后一条语句中插入“AVL”(原始表格的名称)与使用CTE2,则代码工作正常。但是,里程数不是使用新的经纬度值计算的。

所以就像一个概括:列是纬度,经度。我们需要将这些列转换为在纬度2个字符后和经度3个字符后放置小数点。然后我们需要一个名为Miles的列,它可以计算出给定的纬度和经度值之间的里程数。

任何提示,帮助,指针等,都非常感谢!谢谢!

USE [system] 
GO 
With CTE as 
(SELECT * FROM AVL 
WHERE (DATE_TIME between '01/30/2013 00:00:00' AND 
'01/30/2013 23:59:59') AND radio_name = 'MAS7'), 
CTE2 as 
(select *,row_number() over(partition by Vehicle_ID order by Date_Time) as RN 
FROM CTE) 

SELECT *, sqrt((69.1*(previous.Latitude - next.Latitude))* 
    (69.1*(previous.Latitude-next.Latitude)) + 
    (69.1*(previous.Longitude-next.Longitude)) * 
    cos(next.Latitude/57.3) * (69.1*(previous.longitude-next.Longitude)) * 
    cos(next.Latitude/57.3)) as Miles 
From CTE2 as Previous 
Join CTE2 as Next 
On previous.Vehicle_ID = Next.Vehicle_ID 
AND Previous.RN = 
Next.RN - 1 
select cast(Latitude/1000000.0 as decimal(10, 6)) as Latitude 
    , cast(Longitude/1000000.0 as decimal(10, 6)) as Longitude 
from cte2 

**** ****编辑
期望的结果看起来类似这样:

Latitude Longitude Mileage Radio_Name 
36.158500 115.949833 3.444 MAS7 
36.340000 115.914667 3.443 MAS7 
36.153488 115.944875 4.544 MAS7 

(这是不正确的里程,但它只是一个例子什么我正在寻找结果。)

+1

你能举一个你想要的输出的例子吗? –

+0

请参阅上面的内容。 –

回答

2

请注意the difference between tamp tables, table variables and CTEs

您目前正在使用Common Table Expressions或CTE,它们更类似于derived tables,因为它们只能用于直接跟随它们的一条select(或insert,update等)语句(尽管您可以声明多于一个CTE的声明,如你所做的那样)。因此,当你到达你的第二选择语句时,你的CTE已经超出了范围,你不能再引用它们(或者你必须再次声明它们)。在这种情况下,您可能需要使用table variabletemp table

-- Make a temp table 
SELECT * 
INTO #TempTableName -- Create a new temp table 
FROM AVL 
WHERE DATE_TIME between '01/30/2013 00:00:00' AND '01/30/2013 23:59:59' 
    AND radio_name = 'MAS7' 

-- Check out our new temp table 
SELECT * FROM #TempTableName 

-- Clean up our temp table, though this will automatically happen once the connection is dropped 
DROP TABLE #TempTableName 

此外,与临时表工作时,我会经常检查并在开始和结束拖放:

你可能很容易地通过转换你的CTE定义像下面创建一个临时表我的过程如下所示:

if object_id('tempdb..#TempTableName') is not null begin 
    drop table #TempTableName 
end 

在代码中包含这些东西,如果您在执行实际距离计算时遇到困难,请告诉我们。

+0

我尝试将代码插入临时表中,但仍无法设置实际的里程公式。 –