我有一列coordinate
,其中包含许多逗号分隔的坐标。
现在我要分割这个座标。
例如:如果我有
20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,
那我只想要第一个坐标
log:20.45847832 lat:73.99704207
答案 0 :(得分:1)
如果使用SQL Server 2016及更高版本,则可以使用STRING_SPLIT函数。如果我理解正确,则只想获取给定坐标中的第一个坐标。这个想法是用“,”分割,然后用“-”子串。之后,您可以根据需要选择记录。希望这能回答您的问题。
DECLARE @var VARCHAR(MAX) = '20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,'
SELECT TOP 1 'Log:' + ColumnLog + ' Lat:' + ColumnLat AS Coordinate
FROM (
SELECT
SUBSTRING(VALUE, 1, CHARINDEX('-', VALUE)-1) AS ColumnLog,
SUBSTRING(VALUE, CHARINDEX('-', VALUE) + 1, CHARINDEX('-', VALUE)-1) AS ColumnLat
FROM STRING_SPLIT(@var, ',') WHERE RTRIM(VALUE) <> ''
) X
答案 1 :(得分:0)
提示:请勿将此类值存储在CSV列表中。这打破了1.NF,这是一个非常糟糕的设计。使用此代码修复设计并将这些坐标存储在相关的边表中。尝试使用SQL-Server-2008中引入的GEOGRAPHY abilites。
您可以通过一次操作获得此信息:
DECLARE @YourString VARCHAR(1000)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,';
WITH Casted(AsXml) AS
(
SELECT CAST('<x><y>' + REPLACE(REPLACE(@YourString,',','</y></x><x><y>'),'-','</y><y>') + '</y></x>' AS XML)
.query('/x[y/text()]')
)
SELECT * FROM Casted;
结果
<x>
<y>20.45847832</y>
<y>73.99704207</y>
</x>
<x>
<y>20.45868114</y>
<y>73.99712939</y>
</x>
<x>
<y>20.45849913</y>
<y>73.99750285</y>
</x>
<x>
<y>20.45831804</y>
<y>73.99736981</y>
</x>
<x>
<y>20.45848571</y>
<y>73.99702964</y>
</x>
<x>
<y>20.45851507</y>
<y>73.99715704</y>
</x>
<x>
<y>20.45852753</y>
<y>73.99720817</y>
</x>
<x>
<y>20.45849614</y>
<y>73.99728646</y>
</x>
在XQuery/Xpath
中使用它,如下所示:
WITH Casted AS
(
SELECT CAST('<x><y>' + REPLACE(REPLACE(@YourString,',','</y></x><x><y>'),'-','</y><y>') + '</y></x>' AS XML)
.query('/x[y/text()]') AS AsXml
)
SELECT x.value('y[1]/text()[1]','decimal(12,8)') AS [log]
,x.value('y[2]/text()[1]','decimal(12,8)') AS [lat]
FROM Casted
CROSS APPLY AsXml.nodes('/x') A(x);
您会得到
log lat
20.45847832 73.99704207
20.45868114 73.99712939
20.45849913 73.99750285
20.45831804 73.99736981
20.45848571 73.99702964
20.45851507 73.99715704
20.45852753 73.99720817
20.45849614 73.99728646
答案 2 :(得分:0)
我将其添加为新答案,因为它采用了完全不同的方法:使用SQL-Server-2016 +,您可以使用JSON
功能:
DECLARE @YourString VARCHAR(1000)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,';
SELECT *
FROM OPENJSON('[{"lon":"' + REPLACE(REPLACE(@YourString,',','"},{"lon":"'),'-','","lat":"') + '"}]')
WITH(lon float '$.lon'
,lat float '$.lat');
结果
lon lat
20,45847832 73,99704207
20,45868114 73,99712939
20,45849913 73,99750285
20,45831804 73,99736981
20,45848571 73,99702964
20,45851507 73,99715704
20,45852753 73,99720817
20,45849614 73,99728646
0 NULL
答案 3 :(得分:0)
很抱歉添加第三个答案,但这又是一种全新的方法。
如果您需要问题所陈述格式的第一对坐标,那么这是一个真正的在线用户:
DECLARE @YourString VARCHAR(1000)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,';
SELECT 'log:' + STUFF(LEFT(@YourString,PATINDEX('%,%',@YourString)-1),PATINDEX('%-%',@YourString),1,' lat:');
结果
log:20.45847832 lat:73.99704207
尝试一下
DECLARE @mockupTable TABLE(tagdata VARCHAR(1000));
INSERT INTO @mockupTable VALUES('20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,');
SELECT FirstPair
,LEFT(FirstPair,PATINDEX('%-%',FirstPair)-1) AS lon
,SUBSTRING(FirstPair,PATINDEX('%-%',FirstPair)+1,1000) AS lat
FROM @mockupTable t
CROSS APPLY(SELECT LEFT(tagdata,PATINDEX('%,%',tagdata)-1)) A(FirstPair);
答案 4 :(得分:0)
SQL Server支持spatial data。您可以将此字符串视为MULTIPOINT,对其进行解析并返回其中的第一点,例如:
declare @string nvarchar(200)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646'
declare @point geography=geography::Parse('MULTIPOINT (' + replace(@string,'-', ' ') +')')
.STPointN(1)
select @point.Lat,@point.Long
'MULTIPOINT (' + replace(@string,'-', ' ') +')'
用空格替换-
并创建一个可解析为multipoint的字符串:
MULTIPOINT (20.45847832 73.99704207,20.45868114 73.99712939,20.45849913 73.99750285,20.45831804 73.99736981,20.45848571 73.99702964,20.45851507 73.99715704,20.45852753 73.99720817,20.45849614 73.99728646)
geography::Parse可以解析空间特征的熟知文本表示形式,并将特征本身作为geography对象返回。
之后。 STPointN(1)返回多点中的第一个点。可以通过纬度和经度属性获得坐标
ADO.NET通过Microsoft.Sql.Types库支持空间类型。 geography
个对象作为SqlGeography个实例返回